diff --git a/apps/files_sharing/js/dist/additionalScripts.js b/apps/files_sharing/js/dist/additionalScripts.js index 99584ec5d1feb5ba606e8dcb5d3191a07b82fb80..fbffbf8343983a593f5cfebfe975dd633bd2ddd5 100644 Binary files a/apps/files_sharing/js/dist/additionalScripts.js and b/apps/files_sharing/js/dist/additionalScripts.js differ diff --git a/apps/files_sharing/js/dist/additionalScripts.js.map b/apps/files_sharing/js/dist/additionalScripts.js.map index acb3b5036f9dbf2e7bbf9604a32f528f724eae4c..0aa21c13eed36561244367e414a616aa13b1a0b4 100644 Binary files a/apps/files_sharing/js/dist/additionalScripts.js.map and b/apps/files_sharing/js/dist/additionalScripts.js.map differ diff --git a/apps/files_sharing/js/dist/collaboration.js b/apps/files_sharing/js/dist/collaboration.js index ccb6cbb3a6fdb55a883305b5099538b5bf373e19..aaa791a90479e3217d7c55754944ac1a3f8d5810 100644 Binary files a/apps/files_sharing/js/dist/collaboration.js and b/apps/files_sharing/js/dist/collaboration.js differ diff --git a/apps/files_sharing/js/dist/collaboration.js.map b/apps/files_sharing/js/dist/collaboration.js.map index 92ecada8231fdc57497220e01987315fdaa2b5ee..294bc0763a6711731299580d7e33c0f772d29eaa 100644 Binary files a/apps/files_sharing/js/dist/collaboration.js.map and b/apps/files_sharing/js/dist/collaboration.js.map differ diff --git a/apps/files_sharing/js/dist/files_sharing.4.js b/apps/files_sharing/js/dist/files_sharing.4.js deleted file mode 100644 index 67f521750efa62d33e4d8375befaaa8e9a47b69e..0000000000000000000000000000000000000000 Binary files a/apps/files_sharing/js/dist/files_sharing.4.js and /dev/null differ diff --git a/apps/files_sharing/js/dist/files_sharing.4.js.map b/apps/files_sharing/js/dist/files_sharing.4.js.map deleted file mode 100644 index 4ff67fc9c1d1b935188ab8653b4d42f551201094..0000000000000000000000000000000000000000 Binary files a/apps/files_sharing/js/dist/files_sharing.4.js.map and /dev/null differ diff --git a/apps/files_sharing/js/dist/files_sharing.5.js b/apps/files_sharing/js/dist/files_sharing.5.js deleted file mode 100644 index 4b158e0848a7c761e90eeedaf0cf07e0230fbcc3..0000000000000000000000000000000000000000 Binary files a/apps/files_sharing/js/dist/files_sharing.5.js and /dev/null differ diff --git a/apps/files_sharing/js/dist/files_sharing.5.js.map b/apps/files_sharing/js/dist/files_sharing.5.js.map deleted file mode 100644 index f31d33ef1989c81cfc2df66eab4ec738062bff48..0000000000000000000000000000000000000000 Binary files a/apps/files_sharing/js/dist/files_sharing.5.js.map and /dev/null differ diff --git a/apps/files_sharing/js/dist/files_sharing.js b/apps/files_sharing/js/dist/files_sharing.js index 026c19fe59ecf813a4ffe8f6541e0c184d1debbc..fbc11b2181132260add7fc069f80f7461fe648b2 100644 Binary files a/apps/files_sharing/js/dist/files_sharing.js and b/apps/files_sharing/js/dist/files_sharing.js differ diff --git a/apps/files_sharing/js/dist/files_sharing.js.map b/apps/files_sharing/js/dist/files_sharing.js.map index b5fa83a40bb6c0640953a8a503b1fbcaf1e183b8..07e1802b39374f6f7e86eebeb8e88bbf6e9a013c 100644 Binary files a/apps/files_sharing/js/dist/files_sharing.js.map and b/apps/files_sharing/js/dist/files_sharing.js.map differ diff --git a/apps/files_sharing/js/dist/files_sharing_tab.js b/apps/files_sharing/js/dist/files_sharing_tab.js index 4822c29f503a740e4b126a21d0fe49b5b1ff3d7a..eda5205c1d35e7a3c0689a85addd41e02b629a43 100644 Binary files a/apps/files_sharing/js/dist/files_sharing_tab.js and b/apps/files_sharing/js/dist/files_sharing_tab.js differ diff --git a/apps/files_sharing/js/dist/files_sharing_tab.js.map b/apps/files_sharing/js/dist/files_sharing_tab.js.map index b2d234dc3207b6bfb4d1ad0d81ac7d5734ef07a5..b8aa9d37f1244a5fb32895caea89c4852dfcc428 100644 Binary files a/apps/files_sharing/js/dist/files_sharing_tab.js.map and b/apps/files_sharing/js/dist/files_sharing_tab.js.map differ diff --git a/apps/files_sharing/src/additionalScripts.js b/apps/files_sharing/src/additionalScripts.js index db65a2d2085e23a8d4b6907e7ebe2ab03e693d19..dae47b3db12627db96ad0a3f4ca12da31e56add7 100644 --- a/apps/files_sharing/src/additionalScripts.js +++ b/apps/files_sharing/src/additionalScripts.js @@ -1,8 +1,6 @@ import './share' -import './sharetabview' import './sharebreadcrumbview' -import './style/sharetabview.scss' import './style/sharebreadcrumb.scss' import './collaborationresourceshandler.js' diff --git a/apps/files_sharing/src/share.js b/apps/files_sharing/src/share.js index c7ef39897d077f501b1bbbd2718da053969d2f01..a59cfda4b12c920cef8e32a9417bd92ef78aeb21 100644 --- a/apps/files_sharing/src/share.js +++ b/apps/files_sharing/src/share.js @@ -20,10 +20,31 @@ if (!OCA.Sharing) { OCA.Sharing = {} } + + OC.Share = _.extend(OC.Share || {}, { + SHARE_TYPE_USER: 0, + SHARE_TYPE_GROUP: 1, + SHARE_TYPE_LINK: 3, + SHARE_TYPE_EMAIL: 4, + SHARE_TYPE_REMOTE: 6, + SHARE_TYPE_CIRCLE: 7, + SHARE_TYPE_GUEST: 8, + SHARE_TYPE_REMOTE_GROUP: 9, + SHARE_TYPE_ROOM: 10 + }) + /** * @namespace */ OCA.Sharing.Util = { + + /** + * Regular expression for splitting parts of remote share owners: + * "user@example.com/path/to/owncloud" + * "user@anotherexample.com@example.com/path/to/owncloud + */ + _REMOTE_OWNER_REGEXP: new RegExp('^([^@]*)@(([^@]*)@)?([^/]*)([/](.*)?)?$'), + /** * Initialize the sharing plugin. * @@ -210,9 +231,7 @@ }) // register share breadcrumbs component - var shareTab = new OCA.Sharing.ShareTabView('sharing', {order: -20}) - - var breadCrumbSharingDetailView = new OCA.Sharing.ShareBreadCrumbView({ shareTab: shareTab }) + var breadCrumbSharingDetailView = new OCA.Sharing.ShareBreadCrumbView() fileList.registerBreadCrumbDetailView(breadCrumbSharingDetailView) }, @@ -247,15 +266,228 @@ * @returns {boolean} true if the icon was set, false otherwise */ _updateFileActionIcon: function($tr, hasUserShares, hasLinkShares) { + console.info('object'); // if the statuses are loaded already, use them for the icon // (needed when scrolling to the next page) if (hasUserShares || hasLinkShares || $tr.attr('data-share-recipient-data') || $tr.attr('data-share-owner')) { - OC.Share.markFileAsShared($tr, true, hasLinkShares) + OCA.Sharing.Util._markFileAsShared($tr, true, hasLinkShares) return true } return false }, + /** + * 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 = '<span>' + t('core', 'Shared') + '</span>' + // even if reshared, only show "Shared by" + if (ownerId) { + message = t('core', 'Shared by') + avatars = OCA.Sharing.Util._formatRemoteShare(ownerId, owner, message) + } else if (recipients) { + avatars = OCA.Sharing.Util._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('<span class="hidden-visually">' + t('core', 'Shared') + '</span>').prepend(icon) + } + if (hasLink) { + iconClass = 'icon-public' + } + 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) { + // display avatar of the user + var avatar = '<span class="avatar" data-username="' + escapeHTML(shareWith) + '" title="' + message + ' ' + escapeHTML(shareWithDisplayName) + '"></span>' + var hidden = '<span class="hidden-visually">' + message + ' ' + escapeHTML(shareWithDisplayName) + '</span> ' + return avatar + hidden + } + + var userName = parts[1] + var userDomain = parts[3] + var server = parts[4] + var tooltip = message + ' ' + userName + if (userDomain) { + tooltip += '@' + userDomain + } + if (server) { + if (!userDomain) { + userDomain = '…' + } + tooltip += '@' + server + } + + var html = '<span class="remoteAddress" title="' + escapeHTML(tooltip) + '">' + html += '<span class="username">' + escapeHTML(userName) + '</span>' + if (userDomain) { + html += '<span class="userDomain">@' + escapeHTML(userDomain) + '</span>' + } + html += '</span> ' + 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 = '<span>' + t('core', 'Shared') + '</span>' + // 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('<span class="hidden-visually">' + t('core', 'Shared') + '</span>').prepend(icon) + } + if (hasLink) { + iconClass = 'icon-public' + } + icon.removeClass('icon-shared icon-public').addClass(iconClass) + }, + /** * @param {Array} fileData * @returns {String} diff --git a/apps/files_sharing/src/sharebreadcrumbview.js b/apps/files_sharing/src/sharebreadcrumbview.js index c712229b2ee81247e4de68967016901843458233..5c310501649d440a1aa79f6bdfd21377c3d517a9 100644 --- a/apps/files_sharing/src/sharebreadcrumbview.js +++ b/apps/files_sharing/src/sharebreadcrumbview.js @@ -30,13 +30,6 @@ }, _dirInfo: undefined, - /** @type OCA.Sharing.ShareTabView */ - _shareTab: undefined, - - initialize: function(options) { - this._shareTab = options.shareTab - }, - render: function(data) { this._dirInfo = data.dirInfo || null @@ -72,28 +65,10 @@ dirInfo: self._dirInfo }) }) - this._shareTab.on('sharesChanged', function(shareModel) { - var shareTypes = [] - var shares = shareModel.getSharesWithCurrentItem() - for (var i = 0; i < shares.length; i++) { - if (shareTypes.indexOf(shares[i].share_type) === -1) { - shareTypes.push(shares[i].share_type) - } - } - - if (shareModel.hasLinkShares()) { - shareTypes.push(OC.Share.SHARE_TYPE_LINK) - } - - // Since the dirInfo isn't updated we need to do this dark hackery - self._dirInfo.shareTypes = shareTypes - - self.render({ - dirInfo: self._dirInfo - }) - }) - OCA.Files.App.fileList.showDetailsView(fileInfoModel, 'sharing') + var path = fileInfoModel.attributes.path + '/' + fileInfoModel.attributes.name + OCA.Files.Sidebar.file = path + OCA.Files.Sidebar.activeTab = 'sharing' } }) diff --git a/apps/files_sharing/src/sharetabview.js b/apps/files_sharing/src/sharetabview.js deleted file mode 100644 index da0708b85a681ebb1516b89b20d61f6bb4e8c082..0000000000000000000000000000000000000000 --- a/apps/files_sharing/src/sharetabview.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* @global Handlebars */ - -(function() { - var TEMPLATE - = '<div>' - + '<div class="dialogContainer"></div>' - + '<div id="collaborationResources"></div>' - + '</div>' - - /** - * @memberof OCA.Sharing - */ - var ShareTabView = OCA.Files.DetailTabView.extend( - /** @lends OCA.Sharing.ShareTabView.prototype */ { - id: 'shareTabView', - className: 'tab shareTabView', - - initialize: function(name, options) { - OCA.Files.DetailTabView.prototype.initialize.call(this, name, options) - OC.Plugins.attach('OCA.Sharing.ShareTabView', this) - }, - - template: function(params) { - return TEMPLATE - }, - - getLabel: function() { - return t('files_sharing', 'Sharing') - }, - - getIcon: function() { - return 'icon-shared' - }, - - /** - * Renders this details view - */ - render: function() { - var self = this - if (this._dialog) { - // remove/destroy older instance - this._dialog.model.off() - this._dialog.remove() - this._dialog = null - } - - if (this.model) { - this.$el.html(this.template()) - - if (_.isUndefined(this.model.get('sharePermissions'))) { - this.model.set('sharePermissions', OCA.Sharing.Util.getSharePermissions(this.model.attributes)) - } - - // TODO: the model should read these directly off the passed fileInfoModel - var attributes = { - itemType: this.model.isDirectory() ? 'folder' : 'file', - itemSource: this.model.get('id'), - possiblePermissions: this.model.get('sharePermissions') - } - var configModel = new OC.Share.ShareConfigModel() - var shareModel = new OC.Share.ShareItemModel(attributes, { - configModel: configModel, - fileInfoModel: this.model - }) - this._dialog = new OC.Share.ShareDialogView({ - configModel: configModel, - model: shareModel - }) - this.$el.find('.dialogContainer').append(this._dialog.$el) - this._dialog.render() - this._dialog.model.fetch() - this._dialog.model.on('change', function() { - self.trigger('sharesChanged', shareModel) - }) - - import('./collaborationresources').then((Resources) => { - var vm = new Resources.Vue({ - el: '#collaborationResources', - render: h => h(Resources.View), - data: { - model: this.model.toJSON() - } - }) - this.model.on('change', () => { vm.data = this.model.toJSON() }) - - }) - - } else { - this.$el.empty() - // TODO: render placeholder text? - } - this.trigger('rendered') - } - }) - - OCA.Sharing.ShareTabView = ShareTabView -})() diff --git a/apps/files_sharing/src/style/sharetabview.scss b/apps/files_sharing/src/style/sharetabview.scss deleted file mode 100644 index d10808a7488aba82b636de201da381f89f5a9e1b..0000000000000000000000000000000000000000 --- a/apps/files_sharing/src/style/sharetabview.scss +++ /dev/null @@ -1,293 +0,0 @@ -.app-files .shareTabView { - min-height: 100px; -} - -.share-autocomplete-item { - display: flex; - - &.merged { - margin-left: 32px; - } - .autocomplete-item-text { - margin-left: 10px; - margin-right: 10px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - line-height: 32px; - vertical-align: middle; - flex-grow: 1; - .ui-state-highlight { - border: none; - margin: 0; - } - } - &.with-description { - .autocomplete-item-text { - line-height: 100%; - } - } - .autocomplete-item-details { - display: block; - line-height: 130%; - font-size: 90%; - opacity: 0.7; - } - - .icon { - opacity: .7; - margin-right: 7px; - } - .icon.search-globally { - width: 32px; - height: 32px; - margin-right: 0; - } -} - -.shareTabView { - .oneline { - white-space: nowrap; - position: relative; - } - .shareWithLoading { - padding-left: 10px; - right: 35px; - top: 3px; - } - .shareWithConfirm { - position: absolute; - right: 2px; - top: 6px; - padding: 14px; - opacity: 0.5; - } - .shareWithField:focus ~ .shareWithConfirm { - opacity: 1; - } - .linkMore { - position: absolute; - right: -7px; - top: -4px; - padding: 14px; - } - .popovermenu { - .linkPassMenu { - input.error { - border-color: var(--color-error) !important; - &[type="submit"] { - border-left: none; - } - } - .share-pass-submit { - width: auto !important; - } - .icon-loading-small { - background-color: var(--color-main-background); - position: absolute; - right: 8px; - margin: 3px; - padding: 10px; - width: 32px; - height: 32px; - z-index: 10; - } - } - .datepicker { - margin-left: 35px; - } - .share-add { - input.share-note-delete { - border: none; - background-color: transparent; - width: 44px !important; - padding: 0; - flex: 0 0 44px; - margin-left: auto; - &.hidden { - display: none; - } - } - } - // note - .share-note-form { - span.icon-note { - position: relative; - } - textarea.share-note { - margin: 0; - width: 200px; - min-height: 70px; - resize: none; - + input.share-note-submit { - position: absolute; - width: 44px !important; - height: 44px; - bottom: 0px; - right: 10px; - margin: 0; - background-color: transparent; - border: none; - opacity: .7; - &:hover, - &:focus, - &:active { - opacity: 1; - } - } - } - // fix for popover link share - &.share-note-link { - margin-bottom: 10px; - } - } - - /* Border above last entry '+ Add another share' to separate it from current link settings */ - .new-share { - border-top: 1px solid var(--color-border); - } - } - .linkPass .icon-loading-small { - margin-right: 0px; - } - .icon { - background-size: 16px 16px; - } - .shareWithList .icon-loading-small:not(.hidden) + span, - .linkShareView .icon-loading-small:not(.hidden) + input + label:before { - /* Hide if loader is visible */ - display: none !important; - } - input { - &[type='checkbox'] { - margin: 0 3px 0 8px; - vertical-align: middle; - } - &[type='text'] { - &.shareWithField, - &.emailField { - width: 100%; - box-sizing: border-box; - padding-right: 32px; - text-overflow: ellipsis; - } - } - &[type='text'].linkText - &[type='password'].linkPassText, - &[type='password'].passwordField { - width: 180px !important; - } - } - form { - font-size: 100%; - margin-left: 0; - margin-right: 0; - } - // share note on the sidebar - .share-note { - border-radius: var(--border-radius); - margin-bottom: 10px; - margin-left: 37px; - } -} - -// Sharing tab users list -.shareWithList { - list-style-type: none; - display: flex; - flex-direction: column; - > li { - height: 44px; - white-space: normal; - display: inline-flex; - align-items: center; - position: relative; - .avatar { - width: 32px; - height: 32px; - background-color: var(--color-primary); - } - } - .unshare img { - vertical-align: text-bottom; - /* properly align icons */ - } - .sharingOptionsGroup { - margin-left: auto; - display: flex; - align-items: center; - white-space: nowrap; - - // icons - > .icon:not(.hidden), - .share-menu > .icon:not(.hidden) { - padding: 14px; - height: 44px; - width: 44px; - opacity: .5; - display: block; - cursor: pointer; - - &:hover, - &:focus, - &:active { - opacity: .7;; - } - } - - // more menu - > .share-menu { - position: relative; - display: block; - } - } - .username { - padding: 0 8px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } -} - -.ui-autocomplete { - /* limit dropdown height to 6 1/2 entries */ - max-height: calc(36px * 6.5); - overflow-y: auto; - overflow-x: hidden; - z-index: 1550 !important; -} - -.notCreatable { - padding-left: 12px; - padding-top: 12px; - color: var(--color-text-lighter); -} - -.contactsmenu-popover { - left: -6px; - right: auto; - padding: 3px 6px; - top: 100%; - margin-top: 0; - li.hidden { - display: none !important; - } - &:after { - left: 8px; - right: auto; - } -} - -.reshare, -#link label, -#expiration label { - display: inline-flex; - align-items: center; - .avatar { - margin-right: 5px; - } -} - -.resharerInfoView.subView { - position: relative; -} diff --git a/apps/files_sharing/src/utils/SharedWithMe.js b/apps/files_sharing/src/utils/SharedWithMe.js index b2e2e34a9bbdaf07e84ac517ed380ca02798d256..43abddc36b416ed41fc27aae4a26cf4405bde76f 100644 --- a/apps/files_sharing/src/utils/SharedWithMe.js +++ b/apps/files_sharing/src/utils/SharedWithMe.js @@ -27,7 +27,7 @@ * @returns {string} the title */ const shareWithTitle = function(share) { - if (share.type === OC.Share.type_GROUP) { + if (share.type === OC.Share.SHARE_TYPE_GROUP) { return t( 'files_sharing', 'Shared with you and the group {group} by {owner}', @@ -38,7 +38,7 @@ const shareWithTitle = function(share) { undefined, { escape: false } ) - } else if (share.type === OC.Share.type_CIRCLE) { + } else if (share.type === OC.Share.SHARE_TYPE_CIRCLE) { return t( 'files_sharing', 'Shared with you and {circle} by {owner}', @@ -49,7 +49,7 @@ const shareWithTitle = function(share) { undefined, { escape: false } ) - } else if (share.type === OC.Share.type_ROOM) { + } else if (share.type === OC.Share.SHARE_TYPE_ROOM) { if (this.model.get('reshare').share_with_displayname) { return t( 'files_sharing', diff --git a/apps/files_sharing/tests/js/sharedbreadcrumviewSpec.js b/apps/files_sharing/tests/js/sharedbreadcrumviewSpec.js deleted file mode 100644 index 2386a037013c3485187c28717e7c16acb80143bf..0000000000000000000000000000000000000000 --- a/apps/files_sharing/tests/js/sharedbreadcrumviewSpec.js +++ /dev/null @@ -1,240 +0,0 @@ -/** - * @copyright 2016, Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -describe('OCA.Sharing.ShareBreadCrumbView tests', function() { - var BreadCrumb = OCA.Files.BreadCrumb; - var SharedBreadCrum = OCA.Sharing.ShareBreadCrumbView; - - describe('Rendering', function() { - var bc; - var sbc; - var shareTab; - beforeEach(function() { - bc = new BreadCrumb({ - getCrumbUrl: function(part, index) { - // for testing purposes - return part.dir + '#' + index; - } - }); - shareTab = new OCA.Sharing.ShareTabView(); - sbc = new SharedBreadCrum({ - shareTab: shareTab - }); - bc.addDetailView(sbc); - }); - afterEach(function() { - bc = null; - sbc = null; - shareModel = null; - }); - it('Do not render in root', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/', - type: 'dir', - name: '' - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory(''); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(0); - expect(bc.$el.find('.shared').length).toEqual(0); - expect(bc.$el.find('.icon-public').length).toEqual(0); - }); - it('Render in dir', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir' - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory('/foo'); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(1); - expect(bc.$el.find('.shared').length).toEqual(0); - expect(bc.$el.find('.icon-public').length).toEqual(0); - }); - it('Render shared if dir is shared with user', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [OC.Share.SHARE_TYPE_USER] - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory('/foo'); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(1); - expect(bc.$el.find('.shared').length).toEqual(1); - expect(bc.$el.find('.icon-public').length).toEqual(0); - }); - it('Render shared if dir is shared with group', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [OC.Share.SHARE_TYPE_GROUP] - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory('/foo'); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(1); - expect(bc.$el.find('.shared').length).toEqual(1); - expect(bc.$el.find('.icon-public').length).toEqual(0); - }); - it('Render shared if dir is shared by link', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [OC.Share.SHARE_TYPE_LINK] - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory('/foo'); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(0); - expect(bc.$el.find('.shared').length).toEqual(1); - expect(bc.$el.find('.icon-public').length).toEqual(1); - }); - it('Render shared if dir is shared by circle', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [OC.Share.SHARE_TYPE_CIRCLE] - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory('/foo'); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(1); - expect(bc.$el.find('.shared').length).toEqual(1); - expect(bc.$el.find('.icon-public').length).toEqual(0); - }); - it('Render shared if dir is shared with remote', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [OC.Share.SHARE_TYPE_REMOTE] - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory('/foo'); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(1); - expect(bc.$el.find('.shared').length).toEqual(1); - expect(bc.$el.find('.icon-public').length).toEqual(0); - }); - it('Render link shared if at least one is a link share', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [ - OC.Share.SHARE_TYPE_USER, - OC.Share.SHARE_TYPE_GROUP, - OC.Share.SHARE_TYPE_LINK, - OC.Share.SHARE_TYPE_EMAIL, - OC.Share.SHARE_TYPE_REMOTE, - OC.Share.SHARE_TYPE_CIRCLE - ] - }); - bc.setDirectoryInfo(dirInfo); - bc.setDirectory('/foo'); - bc.render(); - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(0); - expect(bc.$el.find('.shared').length).toEqual(1); - expect(bc.$el.find('.icon-public').length).toEqual(1); - }); - it('Remove shared status from user share', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [OC.Share.SHARE_TYPE_USER] - }); - - bc.setDirectory('/foo'); - bc.setDirectoryInfo(dirInfo); - bc.render(); - - var mock = sinon.createStubInstance(OCA.Files.FileList); - mock.showDetailsView = function() { }; - OCA.Files.App.fileList = mock; - var spy = sinon.spy(mock, 'showDetailsView'); - bc.$el.find('.icon-shared').click(); - - expect(spy.calledOnce).toEqual(true); - - var model = sinon.createStubInstance(OC.Share.ShareItemModel); - model.getSharesWithCurrentItem = function() { return [] }; - model.hasLinkShares = function() { return false; }; - - shareTab.trigger('sharesChanged', model); - - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(1); - expect(bc.$el.find('.shared').length).toEqual(0); - expect(bc.$el.find('.icon-public').length).toEqual(0); - }); - it('Add link share to user share', function() { - var dirInfo = new OC.Files.FileInfo({ - id: 42, - path: '/foo', - type: 'dir', - shareTypes: [OC.Share.SHARE_TYPE_USER] - }); - - bc.setDirectory('/foo'); - bc.setDirectoryInfo(dirInfo); - bc.render(); - - var mock = sinon.createStubInstance(OCA.Files.FileList); - mock.showDetailsView = function() { }; - OCA.Files.App.fileList = mock; - var spy = sinon.spy(mock, 'showDetailsView'); - bc.$el.find('.icon-shared').click(); - - expect(spy.calledOnce).toEqual(true); - - var model = sinon.createStubInstance(OC.Share.ShareItemModel); - model.getSharesWithCurrentItem = function() { return [ - {share_type: OC.Share.SHARE_TYPE_USER} - ] }; - model.hasLinkShares = function() { return true; }; - - shareTab.trigger('sharesChanged', model); - - expect(bc.$el.hasClass('breadcrumb')).toEqual(true); - expect(bc.$el.find('.icon-shared').length).toEqual(0); - expect(bc.$el.find('.shared').length).toEqual(1); - expect(bc.$el.find('.icon-public').length).toEqual(1); - }); - }); -}); diff --git a/apps/files_sharing/tests/js/sharedfilelistSpec.js b/apps/files_sharing/tests/js/sharedfilelistSpec.js deleted file mode 100644 index b0b7c1b9b9911a3663b66de80789399c332615e1..0000000000000000000000000000000000000000 --- a/apps/files_sharing/tests/js/sharedfilelistSpec.js +++ /dev/null @@ -1,784 +0,0 @@ -/* - * Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com> - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -describe('OCA.Sharing.FileList tests', function() { - var testFiles, alertStub, notificationStub, fileList; - - beforeEach(function() { - alertStub = sinon.stub(OC.dialogs, 'alert'); - notificationStub = sinon.stub(OC.Notification, 'show'); - - // init parameters and test table elements - $('#testArea').append( - '<div id="app-content-container">' + - // init horrible parameters - '<input type="hidden" id="dir" value="/"></input>' + - '<input type="hidden" id="permissions" value="31"></input>' + - // dummy controls - '<div id="controls">' + - ' <div class="actions creatable"></div>' + - ' <div class="notCreatable"></div>' + - '</div>' + - // dummy table - // TODO: at some point this will be rendered by the fileList class itself! - '<table id="filestable" class="list-container view-grid">' + - '<thead><tr>' + - '<th id="headerName" class="hidden column-name">' + - '<input type="checkbox" id="select_all_files" class="select-all">' + - '<a class="name columntitle" data-sort="name"><span>Name</span><span class="sort-indicator"></span></a>' + - '<span class="selectedActions hidden">' + - '</th>' + - '<th class="hidden column-mtime">' + - '<a class="columntitle" data-sort="mtime"><span class="sort-indicator"></span></a>' + - '</th>' + - '<th class="column-expiration">' + - '<a class="columntitle"><span>Expiration date</span></a>' + - '</th>' + - '</tr></thead>' + - '<tbody id="fileList"></tbody>' + - '<tfoot></tfoot>' + - '</table>' + - '<div id="emptycontent">Empty content message</div>' + - '</div>' - ); - - OC.Plugins.register('OCA.Files.FileList', OCA.Files.TagsPlugin); - }); - afterEach(function() { - testFiles = undefined; - fileList.destroy(); - fileList = undefined; - - notificationStub.restore(); - alertStub.restore(); - }); - - describe('loading file list for incoming shares', function() { - var ocsResponse; - var ocsResponseRemote; - - beforeEach(function() { - fileList = new OCA.Sharing.FileList( - $('#app-content-container'), { - sharedWithUser: true - } - ); - OCA.Sharing.Util.attach(fileList); - - fileList.reload(); - - /* jshint camelcase: false */ - ocsResponse = { - ocs: { - meta: { - status: 'ok', - statuscode: 100, - message: null - }, - data: [{ - id: 7, - item_type: 'file', - item_source: 49, - item_target: '/49', - file_source: 49, - file_target: '/local path/local name.txt', - path: 'files/something shared.txt', - permissions: 31, - stime: 11111, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - tags: [OC.TAG_FAVORITE], - mimetype: 'text/plain', - uid_owner: 'user2', - displayname_owner: 'User Two' - }] - } - }; - - /* jshint camelcase: false */ - ocsResponseRemote = { - ocs: { - meta: { - status: 'ok', - statuscode: 100, - message: null - }, - data: [{ - id: 8, - remote: 'https://foo.bar/', - remote_id: 42, - share_token: 'abc', - name: '/a.txt', - owner: 'user3', - user: 'user1', - mountpoint: '/b.txt', - mountpoint_hash: 'def', - accepted: 1, - mimetype: 'text/plain', - mtime: 22222, - permissions: 31, - type: 'file', - file_id: 1337 - }] - } - }; - - }); - it('render file shares', function() { - expect(fakeServer.requests.length).toEqual(2); - expect(fakeServer.requests[0].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=true&include_tags=true' - ); - - expect(fakeServer.requests[1].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'remote_shares?format=json&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - - fakeServer.requests[1].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponseRemote) - ); - - var $rows = fileList.$el.find('tbody tr'); - expect($rows.length).toEqual(2); - - var $tr = $rows.eq(0); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('local name.txt'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.attr('data-share-owner')).toEqual('User Two'); - expect($tr.attr('data-share-id')).toEqual('7'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + - '/remote.php/webdav/local%20path/local%20name.txt' - ); - expect($tr.find('.nametext').text().trim()).toEqual('local name.txt'); - - $tr = $rows.eq(1); - expect($tr.attr('data-id')).toEqual('1337'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('b.txt'); - expect($tr.attr('data-path')).toEqual(''); - expect($tr.attr('data-size')).not.toBeDefined(); - expect(parseInt($tr.attr('data-permissions'), 10)) - .toEqual(OC.PERMISSION_ALL); // read and delete - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('22222000'); - expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/'); - expect($tr.attr('data-share-id')).toEqual('8'); - expect($tr.attr('data-favorite')).not.toBeDefined(); - expect($tr.attr('data-tags')).toEqual(''); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + - '/remote.php/webdav/b.txt' - ); - expect($tr.find('.nametext').text().trim()).toEqual('b.txt'); - }); - it('render folder shares', function() { - /* jshint camelcase: false */ - ocsResponse.ocs.data[0] = _.extend(ocsResponse.ocs.data[0], { - item_type: 'folder', - file_target: '/local path/local name', - path: 'files/something shared', - }); - - ocsResponseRemote.ocs.data[0] = _.extend(ocsResponseRemote.ocs.data[0], { - type: 'dir', - mimetype: 'httpd/unix-directory', - name: '/a', - mountpoint: '/b' - }); - - expect(fakeServer.requests.length).toEqual(2); - expect(fakeServer.requests[0].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=true&include_tags=true' - ); - expect(fakeServer.requests[1].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'remote_shares?format=json&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - fakeServer.requests[1].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponseRemote) - ); - - var $rows = fileList.$el.find('tbody tr'); - expect($rows.length).toEqual(2); - - var $tr = $rows.eq(0); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('dir'); - expect($tr.attr('data-file')).toEqual('local name'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.attr('data-share-owner')).toEqual('User Two'); - expect($tr.attr('data-share-id')).toEqual('7'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + - '/index.php/apps/files' + - '?dir=/local%20path/local%20name' - ); - expect($tr.find('.nametext').text().trim()).toEqual('local name'); - - $tr = $rows.eq(1); - expect($tr.attr('data-id')).toEqual('1337'); - expect($tr.attr('data-type')).toEqual('dir'); - expect($tr.attr('data-file')).toEqual('b'); - expect($tr.attr('data-path')).toEqual(''); - expect($tr.attr('data-size')).not.toBeDefined(); - expect(parseInt($tr.attr('data-permissions'), 10)) - .toEqual(OC.PERMISSION_ALL); // read and delete - expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); - expect($tr.attr('data-mtime')).toEqual('22222000'); - expect($tr.attr('data-share-owner')).toEqual('user3@foo.bar/'); - expect($tr.attr('data-share-id')).toEqual('8'); - expect($tr.attr('data-favorite')).not.toBeDefined(); - expect($tr.attr('data-tags')).toEqual(''); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + - '/index.php/apps/files' + - '?dir=/b' - ); - expect($tr.find('.nametext').text().trim()).toEqual('b'); - - }); - }); - describe('loading file list for outgoing shares', function() { - var ocsResponse; - - beforeEach(function() { - fileList = new OCA.Sharing.FileList( - $('#app-content-container'), { - sharedWithUser: false - } - ); - OCA.Sharing.Util.attach(fileList); - - fileList.reload(); - - /* jshint camelcase: false */ - ocsResponse = { - ocs: { - meta: { - status: 'ok', - statuscode: 100, - message: null - }, - data: [{ - id: 7, - item_type: 'file', - item_source: 49, - file_source: 49, - path: '/local path/local name.txt', - permissions: 27, - stime: 11111, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user2', - share_with_displayname: 'User Two', - tags: [OC.TAG_FAVORITE], - mimetype: 'text/plain', - uid_owner: 'user1', - displayname_owner: 'User One' - }] - } - }; - }); - it('render file shares', function() { - var request; - - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=false&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - - var $rows = fileList.$el.find('tbody tr'); - var $tr = $rows.eq(0); - expect($rows.length).toEqual(1); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('local name.txt'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.attr('data-share-owner')).not.toBeDefined(); - expect($tr.attr('data-share-id')).toEqual('7'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + - '/remote.php/webdav/local%20path/local%20name.txt' - ); - expect($tr.find('.nametext').text().trim()).toEqual('local name.txt'); - }); - it('render folder shares', function() { - var request; - /* jshint camelcase: false */ - ocsResponse.ocs.data[0] = _.extend(ocsResponse.ocs.data[0], { - item_type: 'folder', - path: '/local path/local name', - }); - - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=false&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - - var $rows = fileList.$el.find('tbody tr'); - var $tr = $rows.eq(0); - expect($rows.length).toEqual(1); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('dir'); - expect($tr.attr('data-file')).toEqual('local name'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.attr('data-share-owner')).not.toBeDefined(); - expect($tr.attr('data-share-id')).toEqual('7'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + - '/index.php/apps/files' + - '?dir=/local%20path/local%20name' - ); - expect($tr.find('.nametext').text().trim()).toEqual('local name'); - }); - it('render link shares', function() { - /* jshint camelcase: false */ - var request; - ocsResponse.ocs.data[0] = { - id: 7, - item_type: 'file', - item_source: 49, - file_source: 49, - path: '/local path/local name.txt', - permissions: 1, - stime: 11111, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - token: 'abc', - mimetype: 'text/plain', - uid_owner: 'user1', - displayname_owner: 'User One', - tags: [OC.TAG_FAVORITE] - }; - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=false&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - - var $rows = fileList.$el.find('tbody tr'); - var $tr = $rows.eq(0); - expect($rows.length).toEqual(1); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('local name.txt'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.attr('data-share-owner')).not.toBeDefined(); - expect($tr.attr('data-share-id')).toEqual('7'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + '/remote.php/webdav/local%20path/local%20name.txt' - ); - - expect($tr.find('.nametext').text().trim()).toEqual('local name.txt'); - }); - it('groups link shares with regular shares', function() { - /* jshint camelcase: false */ - var request; - // link share - ocsResponse.ocs.data.push({ - id: 8, - item_type: 'file', - item_source: 49, - file_source: 49, - path: '/local path/local name.txt', - permissions: 1, - stime: 11111, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - token: 'abc', - mimetype: 'text/plain', - uid_owner: 'user1', - displayname_owner: 'User One', - tags: [OC.TAG_FAVORITE], - }); - // another share of the same file - ocsResponse.ocs.data.push({ - id: 9, - item_type: 'file', - item_source: 49, - file_source: 49, - path: '/local path/local name.txt', - permissions: 27, - stime: 22222, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user3', - share_with_displayname: 'User Three', - mimetype: 'text/plain', - uid_owner: 'user1', - displayname_owner: 'User One' - }); - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=false&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - - var $rows = fileList.$el.find('tbody tr'); - var $tr = $rows.eq(0); - expect($rows.length).toEqual(1); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('local name.txt'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('text/plain'); - // always use the most recent stime - expect($tr.attr('data-mtime')).toEqual('22222000'); - expect($tr.attr('data-share-owner')).not.toBeDefined(); - expect($tr.attr('data-share-id')).toEqual('7,8,9'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + '/remote.php/webdav/local%20path/local%20name.txt' - ); - expect($tr.find('.nametext').text().trim()).toEqual('local name.txt'); - }); - }); - describe('loading file list for link shares', function() { - var ocsResponse; - - beforeEach(function() { - fileList = new OCA.Sharing.FileList( - $('#app-content-container'), { - linksOnly: true - } - ); - OCA.Sharing.Util.attach(fileList); - - fileList.reload(); - - var expirationDateInADay = moment() - .add(1, 'days').format('YYYY-MM-DD HH:mm:ss'); - - /* jshint camelcase: false */ - ocsResponse = { - ocs: { - meta: { - status: 'ok', - statuscode: 100, - message: null - }, - data: [{ - id: 7, - item_type: 'file', - item_source: 49, - file_source: 49, - path: '/local path/local name.txt', - permissions: 1, - stime: 11111, - expiration: null, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - token: 'abc', - mimetype: 'text/plain', - uid_owner: 'user1', - displayname_owner: 'User One', - tags: [OC.TAG_FAVORITE] - },{ - id: 8, - item_type: 'file', - item_source: 50, - file_source: 50, - path: '/local path2/local name2.txt', - permissions: 1, - stime: 11112, - expiration: expirationDateInADay, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - token: 'abcd', - mimetype: 'text/plain2', - uid_owner: 'user2', - displayname_owner: 'User One2' - }] - } - }; - }); - it('render only link shares', function() { - /* jshint camelcase: false */ - var request; - ocsResponse.ocs.data.push({ - // non-link share - id: 8, - item_type: 'file', - item_source: 49, - file_source: 49, - path: '/local path/local name.txt', - permissions: 27, - stime: 11111, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user2', - share_with_displayname: 'User Two', - mimetype: 'text/plain', - uid_owner: 'user1', - displayname_owner: 'User One', - tags: [OC.TAG_FAVORITE] - }); - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=false&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - - // only renders the link share entries - var $rows = fileList.$el.find('tbody tr'); - var $tr = $rows.eq(0); - expect($rows.length).toEqual(2); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('local name.txt'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.attr('data-share-recipient-data')).not.toBeDefined(); - expect($tr.attr('data-share-owner')).not.toBeDefined(); - expect($tr.attr('data-share-id')).toEqual('7'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + '/remote.php/webdav/local%20path/local%20name.txt' - ); - expect($tr.attr('data-expiration')).toEqual('0'); - expect($tr.find('td:last-child span').text()).toEqual(''); - - expect($tr.find('.nametext').text().trim()).toEqual('local name.txt'); - - // change to next row - $tr = $rows.eq(1); - expect($tr.attr('data-id')).toEqual('50'); - expect($tr.attr('data-file')).toEqual('local name2.txt'); - expect($tr.attr('data-expiration')).not.toEqual('0'); - expect($tr.attr('data-favorite')).not.toBeDefined(); - expect($tr.attr('data-tags')).toEqual(''); - expect($tr.find('td:last-child span').text()).toEqual('in a day'); - }); - it('does not show virtual token recipient as recipient when password was set', function() { - /* jshint camelcase: false */ - var request; - // when a password is set, share_with contains an auth token - ocsResponse.ocs.data[0].share_with = 'abc01234/01234abc'; - ocsResponse.ocs.data[0].share_with_displayname = 'abc01234/01234abc'; - expect(fakeServer.requests.length).toEqual(1); - request = fakeServer.requests[0]; - expect(request.url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1') + - 'shares?format=json&shared_with_me=false&include_tags=true' - ); - - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify(ocsResponse) - ); - - // only renders the link share entry - var $rows = fileList.$el.find('tbody tr'); - var $tr = $rows.eq(0); - expect($rows.length).toEqual(2); - expect($tr.attr('data-id')).toEqual('49'); - expect($tr.attr('data-type')).toEqual('file'); - expect($tr.attr('data-file')).toEqual('local name.txt'); - expect($tr.attr('data-path')).toEqual('/local path'); - expect($tr.attr('data-size')).not.toBeDefined(); - expect($tr.attr('data-permissions')).toEqual('31'); // read and delete - expect($tr.attr('data-mime')).toEqual('text/plain'); - expect($tr.attr('data-mtime')).toEqual('11111000'); - expect($tr.attr('data-share-recipient-data')).not.toBeDefined(); - expect($tr.attr('data-share-owner')).not.toBeDefined(); - expect($tr.attr('data-share-id')).toEqual('7'); - expect($tr.attr('data-favorite')).toEqual('true'); - expect($tr.attr('data-tags')).toEqual(OC.TAG_FAVORITE); - expect($tr.find('a.name').attr('href')).toEqual( - OC.getRootPath() + - '/remote.php/webdav/local%20path/local%20name.txt'); - - expect($tr.find('.nametext').text().trim()).toEqual('local name.txt'); - }); - }); - describe('setting share permissions for files', function () { - beforeEach(function () { - - var $content = $('<div id="content"></div>'); - $('#testArea').append($content); - // dummy file list - var $div = $( - '<div>' + - '<table id="filestable" class="list-container view-grid">' + - '<thead></thead>' + - '<tbody id="fileList"></tbody>' + - '</table>' + - '</div>'); - $('#content').append($div); - - fileList = new OCA.Files.FileList($div); - OCA.Sharing.Util.attach(fileList); - }); - - it('external storage root folder', function () { - var $tr; - OC.Share.statuses = {1: {link: false, path: '/subdir'}}; - fileList.setFiles([{ - id: 1, - type: 'dir', - name: 'One.txt', - path: '/subdir', - mimetype: 'text/plain', - size: 12, - permissions: OC.PERMISSION_READ, - sharePermissions: OC.PERMISSION_READ, - etag: 'abc', - shareOwner: 'User One', - recipients: 'User Two', - mountType: 'external-root', - sharePermissions: OC.PERMISSION_READ, - }]); - $tr = fileList.$el.find('tr:first'); - - expect(parseInt($tr.attr('data-share-permissions'), 10)).toEqual(OC.PERMISSION_READ); - }); - - it('external storage root folder reshare', function () { - var $tr; - OC.Share.statuses = {1: {link: false, path: '/subdir'}}; - fileList.setFiles([{ - id: 1, - type: 'dir', - name: 'One.txt', - path: '/subdir', - mimetype: 'text/plain', - size: 12, - permissions: OC.PERMISSION_READ + OC.PERMISSION_SHARE, - sharePermissions: OC.PERMISSION_READ + OC.PERMISSION_SHARE, - etag: 'abc', - shareOwner: 'User One', - recipients: 'User Two', - mountType: 'external-root', - sharePermissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE, - }]); - $tr = fileList.$el.find('tr:first'); - - expect(parseInt($tr.attr('data-share-permissions'), 10)).toEqual(OC.PERMISSION_READ + OC.PERMISSION_SHARE); - }); - - it('external storage root folder file', function () { - var $tr; - OC.Share.statuses = {1: {link: false, path: '/subdir'}}; - fileList.setFiles([{ - id: 1, - type: 'file', - name: 'One.txt', - path: '/subdir', - mimetype: 'text/plain', - size: 12, - permissions: OC.PERMISSION_READ, - sharePermissions: OC.PERMISSION_READ, - etag: 'abc', - shareOwner: 'User One', - recipients: 'User Two', - mountType: 'external-root' - }]); - $tr = fileList.$el.find('tr:first'); - - expect(parseInt($tr.attr('data-share-permissions'), 10)) - .toEqual(OC.PERMISSION_READ); - }); - }); -}); diff --git a/build/compile-handlebars-templates.sh b/build/compile-handlebars-templates.sh index 96d35fa36275afa53a0ddff79a9950de6711f4f6..708be4b9dc7aed0360869fef76b7985396000392 100755 --- a/build/compile-handlebars-templates.sh +++ b/build/compile-handlebars-templates.sh @@ -10,9 +10,6 @@ node node_modules/handlebars/bin/handlebars -n OC.Settings.Templates apps/setti # Systemtags node node_modules/handlebars/bin/handlebars -n OC.SystemTags.Templates core/js/systemtags/templates -f core/js/systemtags/templates.js -# Share -node node_modules/handlebars/bin/handlebars -n OC.Share.Templates core/js/share -f core/js/sharetemplates.js - # Files app node node_modules/handlebars/bin/handlebars -n OCA.Files.Templates apps/files/js/templates -f apps/files/js/templates.js diff --git a/core/js/dist/share_backend.js b/core/js/dist/share_backend.js deleted file mode 100644 index c72516337e2f7ad7b4a9e899d6d19166d4c9fc5a..0000000000000000000000000000000000000000 Binary files a/core/js/dist/share_backend.js and /dev/null differ diff --git a/core/js/dist/share_backend.js.map b/core/js/dist/share_backend.js.map deleted file mode 100644 index f348e16de9b506eb86f2fc80c417bfaa38e02c1e..0000000000000000000000000000000000000000 Binary files a/core/js/dist/share_backend.js.map and /dev/null differ diff --git a/core/js/dist/systemtags.js b/core/js/dist/systemtags.js index b24f4dcce128eacf371ed5e6cc46fa3370bf4b5e..60650e1f2b152ef981e22d0d7078ecef31cc1e9d 100644 Binary files a/core/js/dist/systemtags.js and b/core/js/dist/systemtags.js differ diff --git a/core/js/dist/systemtags.js.map b/core/js/dist/systemtags.js.map index 03d1c3681b9f267f846018d30079620f054032c5..c34ee008c2a963459e133fda80fbd13421affd04 100644 Binary files a/core/js/dist/systemtags.js.map and b/core/js/dist/systemtags.js.map differ diff --git a/core/js/merged-share-backend.js b/core/js/merged-share-backend.js deleted file mode 100644 index b96783603a474e353046e3b7429635181c081771..0000000000000000000000000000000000000000 --- a/core/js/merged-share-backend.js +++ /dev/null @@ -1,9 +0,0 @@ -import './shareconfigmodel.js' -import './sharetemplates.js' -import './shareitemmodel.js' -import './sharesocialmanager.js' -import './sharedialogresharerinfoview.js' -import './sharedialoglinkshareview.js' -import './sharedialogshareelistview.js' -import './sharedialogview.js' -import './share.js' diff --git a/core/js/share.js b/core/js/share.js deleted file mode 100644 index 8dc5e4906475b62f817404869fb435c9b5ca54d7..0000000000000000000000000000000000000000 --- a/core/js/share.js +++ /dev/null @@ -1,399 +0,0 @@ -/* eslint-disable */ -/** - * @namespace - */ -OC.Share = _.extend(OC.Share || {}, { - SHARE_TYPE_USER: 0, - SHARE_TYPE_GROUP: 1, - SHARE_TYPE_LINK: 3, - SHARE_TYPE_EMAIL: 4, - SHARE_TYPE_REMOTE: 6, - SHARE_TYPE_CIRCLE: 7, - SHARE_TYPE_GUEST: 8, - SHARE_TYPE_REMOTE_GROUP: 9, - SHARE_TYPE_ROOM: 10, - - /** - * Regular expression for splitting parts of remote share owners: - * "user@example.com/path/to/owncloud" - * "user@anotherexample.com@example.com/path/to/owncloud - */ - _REMOTE_OWNER_REGEXP: new RegExp('^([^@]*)@(([^@]*)@)?([^/]*)([/](.*)?)?$'), - - /** - * @deprecated use OC.Share.currentShares instead - */ - itemShares: [], - /** - * Full list of all share statuses - */ - statuses: {}, - /** - * Shares for the currently selected file. - * (for which the dropdown is open) - * - * Key is item type and value is an array or - * shares of the given item type. - */ - currentShares: {}, - /** - * Whether the share dropdown is opened. - */ - droppedDown: false, - /** - * Loads ALL share statuses from server, stores them in - * OC.Share.statuses then calls OC.Share.updateIcons() to update the - * files "Share" icon to "Shared" according to their share status and - * share type. - * - * If a callback is specified, the update step is skipped. - * - * @param itemType item type - * @param fileList file list instance, defaults to OCA.Files.App.fileList - * @param callback function to call after the shares were loaded - */ - loadIcons: function(itemType, fileList, callback) { - var path = fileList.dirInfo.path - if (path === '/') { - path = '' - } - path += '/' + fileList.dirInfo.name - - // Load all share icons - $.get( - OC.linkToOCS('apps/files_sharing/api/v1', 2) + 'shares', - { - subfiles: 'true', - path: path, - format: 'json' - }, function(result) { - if (result && result.ocs.meta.statuscode === 200) { - OC.Share.statuses = {} - $.each(result.ocs.data, function(it, share) { - if (!(share.item_source in OC.Share.statuses)) { - OC.Share.statuses[share.item_source] = { link: false } - } - if (share.share_type === OC.Share.SHARE_TYPE_LINK) { - OC.Share.statuses[share.item_source] = { link: true } - } - }) - if (_.isFunction(callback)) { - callback(OC.Share.statuses) - } else { - OC.Share.updateIcons(itemType, fileList) - } - } - } - ) - }, - /** - * Updates the files' "Share" icons according to the known - * sharing states stored in OC.Share.statuses. - * (not reloaded from server) - * - * @param itemType item type - * @param fileList file list instance - * defaults to OCA.Files.App.fileList - */ - updateIcons: function(itemType, fileList) { - var item - var $fileList - var currentDir - if (!fileList && OCA.Files) { - fileList = OCA.Files.App.fileList - } - // fileList is usually only defined in the files app - if (fileList) { - $fileList = fileList.$fileList - currentDir = fileList.getCurrentDirectory() - } - // TODO: iterating over the files might be more efficient - for (item in OC.Share.statuses) { - var iconClass = 'icon-shared' - var data = OC.Share.statuses[item] - var hasLink = data.link - // Links override shared in terms of icon display - if (hasLink) { - iconClass = 'icon-public' - } - if (itemType !== 'file' && itemType !== 'folder') { - $('a.share[data-item="' + item + '"] .icon').removeClass('icon-shared icon-public').addClass(iconClass) - } else { - // TODO: ultimately this part should be moved to files_sharing app - var file = $fileList.find('tr[data-id="' + item + '"]') - var shareFolder = OC.imagePath('core', 'filetypes/folder-shared') - var img - if (file.length > 0) { - this.markFileAsShared(file, true, hasLink) - } else { - var dir = currentDir - if (dir.length > 1) { - var last = '' - var path = dir - // Search for possible parent folders that are shared - while (path != last) { - if (path === data.path && !data.link) { - var actions = $fileList.find('.fileactions .action[data-action="Share"]') - var files = $fileList.find('.filename') - var i - for (i = 0; i < actions.length; i++) { - // TODO: use this.markFileAsShared() - img = $(actions[i]).find('img') - if (img.attr('src') !== OC.imagePath('core', 'actions/public')) { - img.attr('src', image) - $(actions[i]).addClass('permanent') - $(actions[i]).html('<span> ' + t('core', 'Shared') + '</span>').prepend(img) - } - } - for (i = 0; i < files.length; i++) { - if ($(files[i]).closest('tr').data('type') === 'dir') { - $(files[i]).find('.thumbnail').css('background-image', 'url(' + shareFolder + ')') - } - } - } - last = path - path = OC.Share.dirname(path) - } - } - } - } - } - }, - updateIcon: function(itemType, itemSource) { - var shares = false - var link = false - var iconClass = '' - $.each(OC.Share.itemShares, function(index) { - if (OC.Share.itemShares[index]) { - if (index == OC.Share.SHARE_TYPE_LINK) { - if (OC.Share.itemShares[index] == true) { - shares = true - iconClass = 'icon-public' - link = true - - } - } else if (OC.Share.itemShares[index].length > 0) { - shares = true - iconClass = 'icon-shared' - } - } - }) - if (itemType != 'file' && itemType != 'folder') { - $('a.share[data-item="' + itemSource + '"] .icon').removeClass('icon-shared icon-public').addClass(iconClass) - } else { - var $tr = $('tr').filterAttr('data-id', String(itemSource)) - if ($tr.length > 0) { - // it might happen that multiple lists exist in the DOM - // with the same id - $tr.each(function() { - OC.Share.markFileAsShared($(this), shares, link) - }) - } - } - if (shares) { - OC.Share.statuses[itemSource] = OC.Share.statuses[itemSource] || {} - OC.Share.statuses[itemSource].link = link - } else { - delete OC.Share.statuses[itemSource] - } - }, - /** - * 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 = this._REMOTE_OWNER_REGEXP.exec(shareWith) - if (!parts) { - // display avatar of the user - var avatar = '<span class="avatar" data-username="' + escapeHTML(shareWith) + '" title="' + message + ' ' + escapeHTML(shareWithDisplayName) + '"></span>' - var hidden = '<span class="hidden-visually">' + message + ' ' + escapeHTML(shareWithDisplayName) + '</span> ' - return avatar + hidden - } - - var userName = parts[1] - var userDomain = parts[3] - var server = parts[4] - var tooltip = message + ' ' + userName - if (userDomain) { - tooltip += '@' + userDomain - } - if (server) { - if (!userDomain) { - userDomain = '…' - } - tooltip += '@' + server - } - - var html = '<span class="remoteAddress" title="' + escapeHTML(tooltip) + '">' - html += '<span class="username">' + escapeHTML(userName) + '</span>' - if (userDomain) { - html += '<span class="userDomain">@' + escapeHTML(userDomain) + '</span>' - } - html += '</span> ' - 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 = '<span>' + t('core', 'Shared') + '</span>' - // 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('<span class="hidden-visually">' + t('core', 'Shared') + '</span>').prepend(icon) - } - if (hasLink) { - iconClass = 'icon-public' - } - icon.removeClass('icon-shared icon-public').addClass(iconClass) - }, - showDropDown: function(itemType, itemSource, appendTo, link, possiblePermissions, filename) { - var configModel = new OC.Share.ShareConfigModel() - var attributes = { itemType: itemType, itemSource: itemSource, possiblePermissions: possiblePermissions } - var itemModel = new OC.Share.ShareItemModel(attributes, { configModel: configModel }) - var dialogView = new OC.Share.ShareDialogView({ - id: 'dropdown', - model: itemModel, - configModel: configModel, - className: 'drop shareDropDown', - attributes: { - 'data-item-source-name': filename, - 'data-item-type': itemType, - 'data-item-source': itemSource - } - }) - dialogView.setShowLink(link) - var $dialog = dialogView.render().$el - $dialog.appendTo(appendTo) - $dialog.slideDown(OC.menuSpeed, function() { - OC.Share.droppedDown = true - }) - itemModel.fetch() - }, - hideDropDown: function(callback) { - OC.Share.currentShares = null - $('#dropdown').slideUp(OC.menuSpeed, function() { - OC.Share.droppedDown = false - $('#dropdown').remove() - if (typeof FileActions !== 'undefined') { - $('tr').removeClass('mouseOver') - } - if (callback) { - callback.call() - } - }) - }, - dirname: function(path) { - return path.replace(/\\/g, '/').replace(/\/[^\/]*$/, '') - } -}) - -$(document).ready(function() { - if (typeof monthNames !== 'undefined') { - // min date should always be the next day - var minDate = new Date() - minDate.setDate(minDate.getDate() + 1) - $.datepicker.setDefaults({ - monthNames: monthNames, - monthNamesShort: monthNamesShort, - dayNames: dayNames, - dayNamesMin: dayNamesMin, - dayNamesShort: dayNamesShort, - firstDay: firstDay, - minDate: minDate - }) - } - - $(this).click(function(event) { - var target = $(event.target) - var isMatched = !target.is('.drop, .ui-datepicker-next, .ui-datepicker-prev, .ui-icon') - && !target.closest('#ui-datepicker-div').length && !target.closest('.ui-autocomplete').length - if (OC.Share && OC.Share.droppedDown && isMatched && $('#dropdown').has(event.target).length === 0) { - OC.Share.hideDropDown() - } - }) - -}) diff --git a/core/js/share/sharedialoglinkshareview.handlebars b/core/js/share/sharedialoglinkshareview.handlebars deleted file mode 100644 index 5889806e1cac00e3bf1fe3fc7bc56fe753e01cec..0000000000000000000000000000000000000000 --- a/core/js/share/sharedialoglinkshareview.handlebars +++ /dev/null @@ -1,40 +0,0 @@ -{{#if shareAllowed}} -<ul class="shareWithList"> - {{#if nolinkShares}} - <li data-share-id="{{newShareId}}"> - <div class="avatar icon-public-white"></div> - <span class="username">{{newShareLabel}}</span> - <span class="sharingOptionsGroup"> - <div class="share-menu"> - <a href="#" class="icon icon-add new-share has-tooltip {{#if showPending}}hidden{{/if}}" title="{{newShareTitle}}"></a> - <span class="icon icon-loading-small {{#unless showPending}}hidden{{/unless}}"></span> - {{#if showPending}} - {{{pendingPopoverMenu}}} - {{/if}} - </div> - </span> - </li> - {{/if}} - {{#each linkShares}} - <li data-share-id="{{cid}}"> - <div class="avatar icon-public-white"></div> - <span class="username" title="{{linkShareCreationDate}}">{{linkShareLabel}}</span> - - <span class="sharingOptionsGroup"> - <a href="#" class="clipboard-button icon icon-clippy has-tooltip" data-clipboard-text="{{shareLinkURL}}" title="{{copyLabel}}"></a> - <div class="share-menu"> - <a href="#" class="icon icon-more {{#if showPending}}hidden{{/if}}"></a> - <span class="icon icon-loading-small {{#unless showPending}}hidden{{/unless}}"></span> - {{#if showPending}} - {{{pendingPopoverMenu}}} - {{else}} - {{{popoverMenu}}} - {{/if}} - </div> - </span> - </li> - {{/each}} -</ul> -{{else}} -{{#if noSharingPlaceholder}}<input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{noSharingPlaceholder}}" disabled="disabled" />{{/if}} -{{/if}} diff --git a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars deleted file mode 100644 index 2b4873bc56ca4201fa197179b6290ae8005f0f9c..0000000000000000000000000000000000000000 --- a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars +++ /dev/null @@ -1,121 +0,0 @@ -<div class="popovermenu menu"> - <ul> - <li class="hidden linkTextMenu"> - <span class="menuitem icon-link-text"> - <input id="linkText-{{cid}}" class="linkText" type="text" readonly="readonly" value="{{shareLinkURL}}" /> - </span> - </li> - {{#if publicUpload}} - <li> - <span class="menuitem"> - <span class="icon-loading-small hidden"></span> - <input type="radio" name="publicUpload" value="{{publicUploadRValue}}" id="sharingDialogAllowPublicUpload-r-{{cid}}" class="radio publicUploadRadio" {{{publicUploadRChecked}}} /> - <label for="sharingDialogAllowPublicUpload-r-{{cid}}">{{publicUploadRLabel}}</label> - </span> - </li> - <li> - <span class="menuitem"> - <span class="icon-loading-small hidden"></span> - <input type="radio" name="publicUpload" value="{{publicUploadRWValue}}" id="sharingDialogAllowPublicUpload-rw-{{cid}}" class="radio publicUploadRadio" {{{publicUploadRWChecked}}} /> - <label for="sharingDialogAllowPublicUpload-rw-{{cid}}">{{publicUploadRWLabel}}</label> - </span> - </li> - <li> - <span class="menuitem"> - <span class="icon-loading-small hidden"></span> - <input type="radio" name="publicUpload" value="{{publicUploadWValue}}" id="sharingDialogAllowPublicUpload-w-{{cid}}" class="radio publicUploadRadio" {{{publicUploadWChecked}}} /> - <label for="sharingDialogAllowPublicUpload-w-{{cid}}">{{publicUploadWLabel}}</label> - </span> - </li> - {{/if}} - {{#if publicEditing}} - <li id="allowPublicEditingWrapper"> - <span class="menuitem"> - <span class="icon-loading-small hidden"></span> - <input type="checkbox" name="allowPublicEditing" id="sharingDialogAllowPublicEditing-{{cid}}" class="checkbox publicEditingCheckbox" {{{publicEditingChecked}}} /> - <label for="sharingDialogAllowPublicEditing-{{cid}}">{{publicEditingLabel}}</label> - </span> - </li> - {{/if}} - <li> - <span class="menuitem"> - <span class="icon-loading-small hidden"></span> - <input type="checkbox" name="hideDownload" id="sharingDialogHideDownload-{{cid}}" class="checkbox hideDownloadCheckbox" - {{#if hideDownload}}checked="checked"{{/if}} /> - <label for="sharingDialogHideDownload-{{cid}}">{{hideDownloadLabel}}</label> - </span> - </li> - <li> - <span class="menuitem"> - <input type="checkbox" name="showPassword" id="showPassword-{{cid}}" class="checkbox showPasswordCheckbox" - {{#if isPasswordSet}}checked="checked"{{/if}} {{#if isPasswordEnforced}}disabled="disabled"{{/if}} value="1" /> - <label for="showPassword-{{cid}}">{{enablePasswordLabel}}</label> - </span> - </li> - <li class="{{#unless isPasswordSet}}hidden{{/unless}} linkPassMenu"> - <span class="menuitem icon-share-pass"> - <input id="linkPassText-{{cid}}" class="linkPassText" type="password" placeholder="{{passwordPlaceholder}}" autocomplete="new-password" /> - <input type="submit" class="icon-confirm share-pass-submit" value="" /> - <span class="icon icon-loading-small hidden"></span> - </span> - </li> - {{#if showPasswordByTalkCheckBox}} - <li> - <span class="shareOption menuitem"> - <span class="icon-loading-small hidden"></span> - <input type="checkbox" name="passwordByTalk" id="passwordByTalk-{{cid}}" class="checkbox passwordByTalkCheckbox" - {{#if isPasswordByTalkSet}}checked="checked"{{/if}} /> - <label for="passwordByTalk-{{cid}}">{{passwordByTalkLabel}}</label> - </span> - </li> - {{/if}} - <li> - <span class="menuitem"> - <input id="expireDate-{{cid}}" type="checkbox" name="expirationDate" class="expireDate checkbox" - {{#if hasExpireDate}}checked="checked"{{/if}} {{#if isExpirationEnforced}}disabled="disabled"{{/if}} /> - <label for="expireDate-{{cid}}">{{expireDateLabel}}</label> - </span> - </li> - <li class="{{#unless hasExpireDate}}hidden{{/unless}}"> - <span class="menuitem icon-expiredate expirationDateContainer-{{cid}}"> - <label for="expirationDatePicker-{{cid}}" class="hidden-visually" value="{{expirationDate}}">{{expirationLabel}}</label> - <!-- do not use the datepicker if enforced --> - <input id="expirationDatePicker-{{cid}}" class="{{#unless isExpirationEnforced}}datepicker{{/unless}}" type="text" - placeholder="{{expirationDatePlaceholder}}" value="{{#if hasExpireDate}}{{expireDate}}{{else}}{{defaultExpireDate}}{{/if}}" - data-max-date="{{maxDate}}" {{#if isExpirationEnforced}}readonly{{/if}} /> - </span> - </li> - <li> - <a href="#" class="share-add"> - <span class="icon-loading-small hidden"></span> - <span class="icon icon-edit"></span> - <span>{{addNoteLabel}}</span> - <input type="button" class="share-note-delete icon-delete {{#unless hasNote}}hidden{{/unless}}"> - </a> - </li> - <li class="share-note-form share-note-link {{#unless hasNote}}hidden{{/unless}}"> - <span class="menuitem icon-note"> - <textarea class="share-note">{{shareNote}}</textarea> - <input type="submit" class="icon-confirm share-note-submit" value="" id="add-note-{{shareId}}" /> - </span> - </li> - {{#each social}} - <li> - <a href="#" class="menuitem pop-up" data-url="{{url}}" data-window="{{newWindow}}"> - <span class="icon {{iconClass}}"></span> - <span>{{label}}</span> - </a> - </li> - {{/each}} - <li> - <a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span>{{unshareLinkLabel}}</span></a> - </li> - <li> - <a href="#" class="new-share"> - <span class="icon-loading-small hidden"></span> - <span class="icon icon-add"></span> - <span>{{newShareLabel}}</span> - </a> - </li> - </ul> -</div> diff --git a/core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars b/core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars deleted file mode 100644 index d9ff5659fc9044f489a88bd55f05b8a7cb4ab15a..0000000000000000000000000000000000000000 --- a/core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars +++ /dev/null @@ -1,20 +0,0 @@ -<div class="popovermenu open menu pending"> - <ul> - {{#if isPasswordEnforced}} - <li> - <span class="menuitem icon-info"> - <p>{{enforcedPasswordLabel}}</p> - </span> - </li> - <li class="linkPassMenu"> - <span class="menuitem"> - <form autocomplete="off" class="enforcedPassForm"> - <input id="enforcedPassText" required class="enforcedPassText" type="password" - placeholder="{{passwordPlaceholder}}" autocomplete="enforcedPassText" minlength="{{minPasswordLength}}" /> - <input type="submit" value=" " class="primary icon-checkmark-white"> - </form> - </span> - </li> - {{/if}} - </ul> -</div> diff --git a/core/js/share/sharedialogresharerinfoview.handlebars b/core/js/share/sharedialogresharerinfoview.handlebars deleted file mode 100644 index 502356b6332c37ebd7371bc111ce2cad9be80a6c..0000000000000000000000000000000000000000 --- a/core/js/share/sharedialogresharerinfoview.handlebars +++ /dev/null @@ -1,5 +0,0 @@ -<span class="reshare"> - <div class="avatar" data-userName="{{reshareOwner}}"></div> - {{sharedByText}} -</span> -{{#if hasShareNote}}<div class="share-note">{{shareNote}}</div>{{/if}} diff --git a/core/js/share/sharedialogshareelistview.handlebars b/core/js/share/sharedialogshareelistview.handlebars deleted file mode 100644 index 18ff219c12a2077f4661c61b0dc947c510956bdc..0000000000000000000000000000000000000000 --- a/core/js/share/sharedialogshareelistview.handlebars +++ /dev/null @@ -1,32 +0,0 @@ -<ul id="shareWithList" class="shareWithList"> - {{#each sharees}} - {{#unless isShareWithCurrentUser}} - <li data-share-id="{{shareId}}" data-share-type="{{shareType}}" data-share-with="{{shareWith}}"> - <div class="avatar {{#if modSeed}}imageplaceholderseed{{/if}}" data-username="{{shareWith}}" data-avatar="{{shareWithAvatar}}" data-displayname="{{shareWithDisplayName}}" {{#if modSeed}}data-seed="{{shareWith}} {{shareType}}"{{/if}}></div> - <span class="username" title="{{shareWithTitle}}">{{shareWithDisplayName}}</span> - {{#if canUpdateShareSettings }} - <span class="sharingOptionsGroup"> - {{#if editPermissionPossible}} - <span> - <input id="canEdit-{{cid}}-{{shareId}}" type="checkbox" name="edit" class="permissions checkbox" /> - <label for="canEdit-{{cid}}-{{shareId}}">{{canEditLabel}}</label> - </span> - {{/if}} - <div tabindex="0" class="share-menu"><span class="icon icon-more"></span> - {{{popoverMenu}}} - </div> - </span> - {{/if}} - </li> - {{/unless}} - {{/each}} - {{#each linkReshares}} - <li data-share-id="{{shareId}}" data-share-type="{{shareType}}"> - <div class="avatar" data-username="{{shareInitiator}}"></div> - <span class="has-tooltip username" title="{{shareInitiator}}">{{shareInitiatorText}}</span> - <span class="sharingOptionsGroup"> - <a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span class="hidden-visually">{{unshareLabel}}</span></a> - </span> - </li> - {{/each}} -</ul> diff --git a/core/js/share/sharedialogshareelistview_popover_menu.handlebars b/core/js/share/sharedialogshareelistview_popover_menu.handlebars deleted file mode 100644 index 64fe51a3d24ac09f851459adf1a4f01d479c1315..0000000000000000000000000000000000000000 --- a/core/js/share/sharedialogshareelistview_popover_menu.handlebars +++ /dev/null @@ -1,107 +0,0 @@ -<div class="popovermenu bubble hidden menu"> - <ul> - {{#if isResharingAllowed}} {{#if sharePermissionPossible}} {{#unless isMailShare}} - <li> - <span class="menuitem"> - <input id="canShare-{{cid}}-{{shareId}}" type="checkbox" name="share" class="permissions checkbox" {{#if hasSharePermission}}checked="checked"{{/if}} data-permissions="{{sharePermission}}" /> - <label for="canShare-{{cid}}-{{shareId}}">{{canShareLabel}}</label> - </span> - </li> - {{/unless}} {{/if}} {{/if}} - {{#if isFolder}} - {{#if createPermissionPossible}}{{#unless isMailShare}} - <li> - <span class="menuitem"> - <input id="canCreate-{{cid}}-{{shareId}}" type="checkbox" name="create" class="permissions checkbox" {{#if hasCreatePermission}}checked="checked"{{/if}} data-permissions="{{createPermission}}"/> - <label for="canCreate-{{cid}}-{{shareId}}">{{createPermissionLabel}}</label> - </span> - </li> - {{/unless}}{{/if}} - {{#if updatePermissionPossible}}{{#unless isMailShare}} - <li> - <span class="menuitem"> - <input id="canUpdate-{{cid}}-{{shareId}}" type="checkbox" name="update" class="permissions checkbox" {{#if hasUpdatePermission}}checked="checked"{{/if}} data-permissions="{{updatePermission}}"/> - <label for="canUpdate-{{cid}}-{{shareId}}">{{updatePermissionLabel}}</label> - </span> - </li> - {{/unless}}{{/if}} - {{#if deletePermissionPossible}}{{#unless isMailShare}} - <li> - <span class="menuitem"> - <input id="canDelete-{{cid}}-{{shareId}}" type="checkbox" name="delete" class="permissions checkbox" {{#if hasDeletePermission}}checked="checked"{{/if}} data-permissions="{{deletePermission}}"/> - <label for="canDelete-{{cid}}-{{shareId}}">{{deletePermissionLabel}}</label> - </span> - </li> - {{/unless}}{{/if}} - {{/if}} - {{#if isMailShare}} - {{#if hasCreatePermission}} - <li> - <span class="menuitem"> - <input id="secureDrop-{{cid}}-{{shareId}}" type="checkbox" name="secureDrop" class="checkbox secureDrop" {{#if secureDropMode}}checked="checked"{{/if}} data-permissions="{{readPermission}}"/> - <label for="secureDrop-{{cid}}-{{shareId}}">{{secureDropLabel}}</label> - </span> - </li> - {{/if}} - <li> - <span class="menuitem"> - <input id="password-{{cid}}-{{shareId}}" type="checkbox" name="password" class="password checkbox" {{#if isPasswordSet}}checked="checked"{{/if}}{{#if isPasswordSet}}{{#if isPasswordForMailSharesRequired}}disabled=""{{/if}}{{/if}}" /> - <label for="password-{{cid}}-{{shareId}}">{{passwordLabel}}</label> - </span> - </li> - <li class="passwordMenu-{{cid}}-{{shareId}} {{#unless isPasswordSet}}hidden{{/unless}}"> - <span class="passwordContainer-{{cid}}-{{shareId}} icon-passwordmail menuitem"> - <label for="passwordField-{{cid}}-{{shareId}}" class="hidden-visually" value="{{password}}">{{passwordLabel}}</label> - <input id="passwordField-{{cid}}-{{shareId}}" class="passwordField" type="password" placeholder="{{passwordPlaceholder}}" value="{{passwordValue}}" autocomplete="new-password" /> - <span class="icon-loading-small hidden"></span> - </span> - </li> - {{#if isTalkEnabled}} - <li> - <span class="menuitem"> - <input id="passwordByTalk-{{cid}}-{{shareId}}" type="checkbox" name="passwordByTalk" class="passwordByTalk checkbox" {{#if isPasswordByTalkSet}}checked="checked"{{/if}} /> - <label for="passwordByTalk-{{cid}}-{{shareId}}">{{passwordByTalkLabel}}</label> - </span> - </li> - <li class="passwordByTalkMenu-{{cid}}-{{shareId}} {{#unless isPasswordByTalkSet}}hidden{{/unless}}"> - <span class="passwordByTalkContainer-{{cid}}-{{shareId}} icon-passwordtalk menuitem"> - <label for="passwordByTalkField-{{cid}}-{{shareId}}" class="hidden-visually" value="{{password}}">{{passwordByTalkLabel}}</label> - <input id="passwordByTalkField-{{cid}}-{{shareId}}" class="passwordField" type="password" placeholder="{{passwordByTalkPlaceholder}}" value="{{passwordValue}}" autocomplete="new-password" /> - <span class="icon-loading-small hidden"></span> - </span> - </li> - {{/if}} - {{/if}} - <li> - <span class="menuitem"> - <input id="expireDate-{{cid}}-{{shareId}}" type="checkbox" name="expirationDate" class="expireDate checkbox" {{#if hasExpireDate}}checked="checked"{{/if}}" /> - <label for="expireDate-{{cid}}-{{shareId}}">{{expireDateLabel}}</label> - </span> - </li> - <li class="expirationDateMenu-{{cid}}-{{shareId}} {{#unless hasExpireDate}}hidden{{/unless}}"> - <span class="expirationDateContainer-{{cid}}-{{shareId}} icon-expiredate menuitem"> - <label for="expirationDatePicker-{{cid}}-{{shareId}}" class="hidden-visually" value="{{expirationDate}}">{{expirationLabel}}</label> - <input id="expirationDatePicker-{{cid}}-{{shareId}}" class="datepicker" type="text" placeholder="{{expirationDatePlaceholder}}" value="{{#if hasExpireDate}}{{expireDate}}{{else}}{{defaultExpireDate}}{{/if}}" /> - </span> - </li> - {{#if isNoteAvailable}} - <li> - <a href="#" class="share-add"> - <span class="icon-loading-small hidden"></span> - <span class="icon icon-edit"></span> - <span>{{addNoteLabel}}</span> - <input type="button" class="share-note-delete icon-delete {{#unless hasNote}}hidden{{/unless}}"> - </a> - </li> - <li class="share-note-form {{#unless hasNote}}hidden{{/unless}}"> - <span class="menuitem icon-note"> - <textarea class="share-note">{{shareNote}}</textarea> - <input type="submit" class="icon-confirm share-note-submit" value="" id="add-note-{{shareId}}" /> - </span> - </li> - {{/if}} - <li> - <a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span>{{unshareLabel}}</span></a> - </li> - </ul> -</div> diff --git a/core/js/share/sharedialogview.handlebars b/core/js/share/sharedialogview.handlebars deleted file mode 100644 index d3d1a949be760e65acdf73c4e7a5fe59a313fdca..0000000000000000000000000000000000000000 --- a/core/js/share/sharedialogview.handlebars +++ /dev/null @@ -1,12 +0,0 @@ -<div class="resharerInfoView subView"></div> -{{#if isSharingAllowed}} - <label for="shareWith-{{cid}}" class="hidden-visually">{{shareLabel}}</label> - <div class="oneline"> - <input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{sharePlaceholder}}" /> - <span class="shareWithLoading icon-loading-small hidden"></span> - <span class="shareWithConfirm icon icon-confirm"></span> - </div> -{{/if}} -<div class="linkShareView subView"></div> -<div class="shareeListView subView"></div> -<div class="loading hidden" style="height: 50px"></div> diff --git a/core/js/shareconfigmodel.js b/core/js/shareconfigmodel.js deleted file mode 100644 index 0d066116b53596cdd7949be4f1cfb3b282315de3..0000000000000000000000000000000000000000 --- a/core/js/shareconfigmodel.js +++ /dev/null @@ -1,72 +0,0 @@ -/* eslint-disable */ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* global moment, OC */ - -(function() { - if (!OC.Share) { - OC.Share = {} - OC.Share.Types = {} - } - - // FIXME: the config model should populate its own model attributes based on - // the old DOM-based config - var ShareConfigModel = OC.Backbone.Model.extend({ - defaults: { - publicUploadEnabled: false, - enforcePasswordForPublicLink: OC.appConfig.core.enforcePasswordForPublicLink, - enableLinkPasswordByDefault: OC.appConfig.core.enableLinkPasswordByDefault, - isDefaultExpireDateEnforced: OC.appConfig.core.defaultExpireDateEnforced === true, - isDefaultExpireDateEnabled: OC.appConfig.core.defaultExpireDateEnabled === true, - isRemoteShareAllowed: OC.appConfig.core.remoteShareAllowed, - isMailShareAllowed: OC.appConfig.shareByMailEnabled !== undefined, - defaultExpireDate: OC.appConfig.core.defaultExpireDate, - isResharingAllowed: OC.appConfig.core.resharingAllowed, - isPasswordForMailSharesRequired: (OC.appConfig.shareByMail === undefined) ? false : OC.appConfig.shareByMail.enforcePasswordProtection, - allowGroupSharing: OC.appConfig.core.allowGroupSharing - }, - - /** - * @returns {boolean} - */ - isPublicUploadEnabled: function() { - var publicUploadEnabled = $('#filestable').data('allow-public-upload') - return publicUploadEnabled === 'yes' - }, - - /** - * @returns {boolean} - */ - isShareWithLinkAllowed: function() { - return $('#allowShareWithLink').val() === 'yes' - }, - - /** - * @returns {string} - */ - getFederatedShareDocLink: function() { - return OC.appConfig.core.federatedCloudShareDoc - }, - - getDefaultExpirationDateString: function() { - var expireDateString = '' - if (this.get('isDefaultExpireDateEnabled')) { - var date = moment.utc() - var expireAfterDays = this.get('defaultExpireDate') - date.add(expireAfterDays, 'days') - expireDateString = date.format('YYYY-MM-DD 00:00:00') - } - return expireDateString - } - }) - - OC.Share.ShareConfigModel = ShareConfigModel -})() diff --git a/core/js/sharedialoglinkshareview.js b/core/js/sharedialoglinkshareview.js deleted file mode 100644 index 96ebd8ebbac35e6023a8450bc039f815b20fb0f3..0000000000000000000000000000000000000000 --- a/core/js/sharedialoglinkshareview.js +++ /dev/null @@ -1,954 +0,0 @@ -/* eslint-disable */ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* globals Clipboard, Handlebars */ - -(function() { - if (!OC.Share) { - OC.Share = {} - } - - var PASSWORD_PLACEHOLDER = '**********' - var PASSWORD_PLACEHOLDER_MESSAGE = t('core', 'Choose a password for the public link') - var PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL = t('core', 'Choose a password for the public link or press the "Enter" key') - - /** - * @class OCA.Share.ShareDialogLinkShareView - * @member {OC.Share.ShareItemModel} model - * @member {jQuery} $el - * @memberof OCA.Sharing - * @classdesc - * - * Represents the GUI of the share dialogue - * - */ - var ShareDialogLinkShareView = OC.Backbone.View.extend({ - /** @type {string} **/ - id: 'shareDialogLinkShare', - - /** @type {OC.Share.ShareConfigModel} **/ - configModel: undefined, - - /** @type {boolean} **/ - showLink: true, - - /** @type {boolean} **/ - showPending: false, - - /** @type {string} **/ - password: '', - - /** @type {string} **/ - newShareId: 'new-share', - - events: { - // open menu - 'click .share-menu .icon-more': 'onToggleMenu', - // hide download - 'change .hideDownloadCheckbox': 'onHideDownloadChange', - // password - 'click input.share-pass-submit': 'onPasswordEntered', - 'keyup input.linkPassText': 'onPasswordKeyUp', // check for the enter key - 'change .showPasswordCheckbox': 'onShowPasswordClick', - 'change .passwordByTalkCheckbox': 'onPasswordByTalkChange', - 'change .publicEditingCheckbox': 'onAllowPublicEditingChange', - // copy link url - 'click .linkText': 'onLinkTextClick', - // social - 'click .pop-up': 'onPopUpClick', - // permission change - 'change .publicUploadRadio': 'onPublicUploadChange', - // expire date - 'click .expireDate': 'onExpireDateChange', - 'change .datepicker': 'onChangeExpirationDate', - 'click .datepicker': 'showDatePicker', - // note - 'click .share-add': 'showNoteForm', - 'click .share-note-delete': 'deleteNote', - 'click .share-note-submit': 'updateNote', - // remove - 'click .unshare': 'onUnshare', - // new share - 'click .new-share': 'newShare', - // enforced pass set - 'submit .enforcedPassForm': 'enforcedPasswordSet' - }, - - initialize: function(options) { - var view = this - - this.model.on('change:permissions', function() { - view.render() - }) - - this.model.on('change:itemType', function() { - view.render() - }) - - this.model.on('change:allowPublicUploadStatus', function() { - view.render() - }) - - this.model.on('change:hideFileListStatus', function() { - view.render() - }) - - this.model.on('change:linkShares', function(model, linkShares) { - // The "Password protect by Talk" item is shown only when there - // is a password. Unfortunately there is no fine grained - // rendering of items in the link shares, so the whole view - // needs to be rendered again when the password of a share - // changes. - // Note that this event handler is concerned only about password - // changes; other changes in the link shares does not trigger - // a rendering, so the view must be rendered again as needed in - // those cases (for example, when a link share is removed). - - var previousLinkShares = model.previous('linkShares') - if (previousLinkShares.length !== linkShares.length) { - return - } - - var i - for (i = 0; i < linkShares.length; i++) { - if (linkShares[i].id !== previousLinkShares[i].id) { - // A resorting should never happen, but just in case. - return - } - - if (linkShares[i].password !== previousLinkShares[i].password) { - view.render() - - return - } - } - }) - - if (!_.isUndefined(options.configModel)) { - this.configModel = options.configModel - } else { - throw 'missing OC.Share.ShareConfigModel' - } - - var clipboard = new Clipboard('.clipboard-button') - clipboard.on('success', function(e) { - var $trigger = $(e.trigger) - - $trigger.tooltip('hide') - .attr('data-original-title', t('core', 'Copied!')) - .tooltip('fixTitle') - .tooltip({ placement: 'bottom', trigger: 'manual' }) - .tooltip('show') - _.delay(function() { - $trigger.tooltip('hide') - .attr('data-original-title', t('core', 'Copy link')) - .tooltip('fixTitle') - }, 3000) - }) - clipboard.on('error', function(e) { - var $trigger = $(e.trigger) - var $menu = $trigger.next('.share-menu').find('.popovermenu') - var $linkTextMenu = $menu.find('li.linkTextMenu') - var $input = $linkTextMenu.find('.linkText') - - var $li = $trigger.closest('li[data-share-id]') - var shareId = $li.data('share-id') - - // show menu - OC.showMenu(null, $menu) - - var actionMsg = '' - if (/iPhone|iPad/i.test(navigator.userAgent)) { - actionMsg = t('core', 'Not supported!') - } else if (/Mac/i.test(navigator.userAgent)) { - actionMsg = t('core', 'Press ⌘-C to copy.') - } else { - actionMsg = t('core', 'Press Ctrl-C to copy.') - } - - $linkTextMenu.removeClass('hidden') - $input.select() - $input.tooltip('hide') - .attr('data-original-title', actionMsg) - .tooltip('fixTitle') - .tooltip({ placement: 'bottom', trigger: 'manual' }) - .tooltip('show') - _.delay(function() { - $input.tooltip('hide') - $input.attr('data-original-title', t('core', 'Copy')) - .tooltip('fixTitle') - }, 3000) - }) - }, - - newShare: function(event) { - var self = this - var $target = $(event.target) - var $li = $target.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $loading = $li.find('.share-menu > .icon-loading-small') - - if (!$loading.hasClass('hidden') && this.password === '') { - // in process - return false - } - - // hide all icons and show loading - $li.find('.icon').addClass('hidden') - $loading.removeClass('hidden') - - // hide menu - OC.hideMenus() - - var shareData = {} - - var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink') - var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced') - - // set default expire date - if (isExpirationEnforced) { - var defaultExpireDays = this.configModel.get('defaultExpireDate') - var expireDate = moment().add(defaultExpireDays, 'day').format('DD-MM-YYYY') - shareData.expireDate = expireDate - } - - // if password is set, add to data - if (isPasswordEnforced && this.password !== '') { - shareData.password = this.password - } - - var newShareId = false - - // We need a password before the share creation - if (isPasswordEnforced && !this.showPending && this.password === '') { - this.showPending = shareId - var self = this.render() - self.$el.find('.pending #enforcedPassText').focus() - } else { - // else, we have a password or it is not enforced - $.when(this.model.saveLinkShare(shareData, { - success: function() { - $loading.addClass('hidden') - $li.find('.icon').removeClass('hidden') - self.render() - // open the menu by default - // we can only do that after the render - if (newShareId) { - var shares = self.$el.find('li[data-share-id]') - var $newShare = self.$el.find('li[data-share-id="' + newShareId + '"]') - } - }, - error: function() { - // empty function to override the default Dialog warning - } - })).fail(function(response) { - // password failure? Show error - self.password = '' - if (isPasswordEnforced && response && response.responseJSON && response.responseJSON.ocs.meta && response.responseJSON.ocs.meta.message) { - var $input = self.$el.find('.pending #enforcedPassText') - $input.tooltip('destroy') - $input.attr('title', response.responseJSON.ocs.meta.message) - $input.tooltip({ placement: 'bottom', trigger: 'manual' }) - $input.tooltip('show') - } else { - OC.Notification.showTemporary(t('core', 'Unable to create a link share')) - $loading.addClass('hidden') - $li.find('.icon').removeClass('hidden') - } - }).then(function(response) { - // resolve before success - newShareId = response.ocs.data.id - }) - } - }, - - enforcedPasswordSet: function(event) { - event.preventDefault() - var $form = $(event.target) - var $input = $form.find('input.enforcedPassText') - this.password = $input.val() - this.showPending = false - this.newShare(event) - }, - - onLinkTextClick: function(event) { - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var $el = $li.find('.linkText') - $el.focus() - $el.select() - }, - - onHideDownloadChange: function(event) { - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $checkbox = $li.find('.hideDownloadCheckbox') - $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock') - - var hideDownload = false - if ($checkbox.is(':checked')) { - hideDownload = true - } - - this.model.saveLinkShare({ - hideDownload: hideDownload, - cid: shareId - }, { - success: function() { - $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock') - }, - error: function(obj, msg) { - OC.Notification.showTemporary(t('core', 'Unable to toggle this option')) - $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock') - } - }) - }, - - onShowPasswordClick: function(event) { - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - $li.find('.linkPass').slideToggle(OC.menuSpeed) - $li.find('.linkPassMenu').toggleClass('hidden') - if (!$li.find('.showPasswordCheckbox').is(':checked')) { - this.model.saveLinkShare({ - password: '', - cid: shareId - }) - } else { - if (!OC.Util.isIE()) { - $li.find('.linkPassText').focus() - } - } - }, - - onPasswordKeyUp: function(event) { - if (event.keyCode === 13) { - this.onPasswordEntered(event) - } - }, - - onPasswordEntered: function(event) { - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $loading = $li.find('.linkPassMenu .icon-loading-small') - if (!$loading.hasClass('hidden')) { - // still in process - return - } - var $input = $li.find('.linkPassText') - $input.removeClass('error') - $input.parent().find('input').removeClass('error') - var password = $input.val() - - if ($li.find('.linkPassText').attr('placeholder') === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) { - - // in IE9 the password might be the placeholder due to bugs in the placeholders polyfill - if (password === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) { - password = '' - } - } else { - - // in IE9 the password might be the placeholder due to bugs in the placeholders polyfill - if (password === '' || password === PASSWORD_PLACEHOLDER || password === PASSWORD_PLACEHOLDER_MESSAGE) { - return - } - } - - $loading - .removeClass('hidden') - .addClass('inlineblock') - - this.model.saveLinkShare({ - password: password, - cid: shareId - }, { - complete: function(model) { - $loading.removeClass('inlineblock').addClass('hidden') - }, - error: function(model, msg) { - // Add visual feedback to both the input and the submit button - $input.parent().find('input').addClass('error') - - // destroy old tooltips - var $container = $input.parent() - $container.tooltip('destroy') - $input.addClass('error') - $container.attr('title', msg) - $container.tooltip({ placement: 'bottom', trigger: 'manual' }) - $container.tooltip('show') - } - }) - }, - - onPasswordByTalkChange: function(event) { - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $checkbox = $li.find('.passwordByTalkCheckbox') - $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock') - - var sendPasswordByTalk = false - if ($checkbox.is(':checked')) { - sendPasswordByTalk = true - } - - this.model.saveLinkShare({ - sendPasswordByTalk: sendPasswordByTalk, - cid: shareId - }, { - success: function() { - $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock') - }, - error: function(obj, msg) { - OC.Notification.showTemporary(t('core', 'Unable to toggle this option')) - $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock') - } - }) - }, - - onAllowPublicEditingChange: function(event) { - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $checkbox = $li.find('.publicEditingCheckbox') - $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock') - - var permissions = OC.PERMISSION_READ - if ($checkbox.is(':checked')) { - permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_READ - } - - this.model.saveLinkShare({ - permissions: permissions, - cid: shareId - }, { - success: function() { - $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock') - }, - error: function(obj, msg) { - OC.Notification.showTemporary(t('core', 'Unable to toggle this option')) - $checkbox.siblings('.icon-loading-small').addClass('hidden').removeClass('inlineblock') - } - }) - }, - - onPublicUploadChange: function(event) { - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var permissions = event.currentTarget.value - this.model.saveLinkShare({ - permissions: permissions, - cid: shareId - }) - }, - - showNoteForm: function(event) { - event.preventDefault() - event.stopPropagation() - var self = this - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var $menu = $element.closest('li') - var $form = $menu.next('li.share-note-form') - - // show elements - $menu.find('.share-note-delete').toggleClass('hidden') - $form.toggleClass('hidden') - $form.find('textarea').focus() - }, - - deleteNote: function(event) { - event.preventDefault() - event.stopPropagation() - var self = this - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $menu = $element.closest('li') - var $form = $menu.next('li.share-note-form') - - $form.find('.share-note').val('') - - $form.addClass('hidden') - $menu.find('.share-note-delete').addClass('hidden') - - self.sendNote('', shareId, $menu) - }, - - updateNote: function(event) { - event.preventDefault() - event.stopPropagation() - var self = this - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $form = $element.closest('li.share-note-form') - var $menu = $form.prev('li') - var message = $form.find('.share-note').val().trim() - - if (message.length < 1) { - return - } - - self.sendNote(message, shareId, $menu) - }, - - sendNote: function(note, shareId, $menu) { - var $form = $menu.next('li.share-note-form') - var $submit = $form.find('input.share-note-submit') - var $error = $form.find('input.share-note-error') - - $submit.prop('disabled', true) - $menu.find('.icon-loading-small').removeClass('hidden') - $menu.find('.icon-edit').hide() - - var complete = function() { - $submit.prop('disabled', false) - $menu.find('.icon-loading-small').addClass('hidden') - $menu.find('.icon-edit').show() - } - var error = function() { - $error.show() - setTimeout(function() { - $error.hide() - }, 3000) - } - - // send data - $.ajax({ - method: 'PUT', - url: OC.linkToOCS('apps/files_sharing/api/v1/shares', 2) + shareId + '?' + OC.buildQueryString({ format: 'json' }), - data: { note: note }, - complete: complete, - error: error - }) - }, - - render: function() { - this.$el.find('.has-tooltip').tooltip() - - // reset previously set passwords - this.password = '' - - var linkShareTemplate = this.template() - var resharingAllowed = this.model.sharePermissionPossible() - - if (!resharingAllowed - || !this.showLink - || !this.configModel.isShareWithLinkAllowed()) { - var templateData = { shareAllowed: false } - if (!resharingAllowed) { - // add message - templateData.noSharingPlaceholder = t('core', 'Resharing is not allowed') - } - this.$el.html(linkShareTemplate(templateData)) - return this - } - - var publicUpload - = this.model.isFolder() - && this.model.createPermissionPossible() - && this.configModel.isPublicUploadEnabled() - - var publicEditingChecked = '' - if (this.model.isPublicEditingAllowed()) { - publicEditingChecked = 'checked="checked"' - } - - var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink') - var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true - var passwordPlaceholderInitial = this.configModel.get('enforcePasswordForPublicLink') - ? PASSWORD_PLACEHOLDER_MESSAGE : PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL - - var publicEditable - = !this.model.isFolder() - && this.model.updatePermissionPossible() - - var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced') - - // what if there is another date picker on that page? - var minDate = new Date() - // min date should always be the next day - minDate.setDate(minDate.getDate() + 1) - - $.datepicker.setDefaults({ - minDate: minDate - }) - - this.$el.find('.datepicker').datepicker({ dateFormat: 'dd-mm-yy' }) - - var minPasswordLength = 4 - // password policy? - if (OC.getCapabilities().password_policy && OC.getCapabilities().password_policy.minLength) { - minPasswordLength = OC.getCapabilities().password_policy.minLength - } - - var popoverBase = { - urlLabel: t('core', 'Link'), - hideDownloadLabel: t('core', 'Hide download'), - enablePasswordLabel: isPasswordEnforced ? t('core', 'Password protection enforced') : t('core', 'Password protect'), - passwordLabel: t('core', 'Password'), - passwordPlaceholderInitial: passwordPlaceholderInitial, - publicUpload: publicUpload, - publicEditing: publicEditable, - publicEditingChecked: publicEditingChecked, - publicEditingLabel: t('core', 'Allow editing'), - mailPrivatePlaceholder: t('core', 'Email link to person'), - mailButtonText: t('core', 'Send'), - publicUploadRWLabel: t('core', 'Allow upload and editing'), - publicUploadRLabel: t('core', 'Read only'), - publicUploadWLabel: t('core', 'File drop (upload only)'), - publicUploadRWValue: OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE, - publicUploadRValue: OC.PERMISSION_READ, - publicUploadWValue: OC.PERMISSION_CREATE, - expireDateLabel: isExpirationEnforced ? t('core', 'Expiration date enforced') : t('core', 'Set expiration date'), - expirationLabel: t('core', 'Expiration'), - expirationDatePlaceholder: t('core', 'Expiration date'), - isExpirationEnforced: isExpirationEnforced, - isPasswordEnforced: isPasswordEnforced, - defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today - addNoteLabel: t('core', 'Note to recipient'), - unshareLabel: t('core', 'Unshare'), - unshareLinkLabel: t('core', 'Delete share link'), - newShareLabel: t('core', 'Add another link') - } - - var pendingPopover = { - isPasswordEnforced: isPasswordEnforced, - enforcedPasswordLabel: t('core', 'Password protection for links is mandatory'), - passwordPlaceholder: passwordPlaceholderInitial, - minPasswordLength: minPasswordLength - } - var pendingPopoverMenu = this.pendingPopoverMenuTemplate(_.extend({}, pendingPopover)) - - var linkShares = this.getShareeList() - if (_.isArray(linkShares)) { - for (var i = 0; i < linkShares.length; i++) { - var social = [] - OC.Share.Social.Collection.each(function(model) { - var url = model.get('url') - url = url.replace('{{reference}}', linkShares[i].shareLinkURL) - social.push({ - url: url, - label: t('core', 'Share to {name}', { name: model.get('name') }), - name: model.get('name'), - iconClass: model.get('iconClass'), - newWindow: model.get('newWindow') - }) - }) - var popover = this.getPopoverObject(linkShares[i]) - linkShares[i].popoverMenu = this.popoverMenuTemplate(_.extend({}, popoverBase, popover, { social: social })) - linkShares[i].pendingPopoverMenu = pendingPopoverMenu - } - } - - this.$el.html(linkShareTemplate({ - linkShares: linkShares, - shareAllowed: true, - nolinkShares: linkShares.length === 0, - newShareLabel: t('core', 'Share link'), - newShareTitle: t('core', 'New share link'), - pendingPopoverMenu: pendingPopoverMenu, - showPending: this.showPending === this.newShareId, - newShareId: this.newShareId - })) - - this.delegateEvents() - - // new note autosize - autosize(this.$el.find('.share-note-form .share-note')) - - return this - }, - - onToggleMenu: function(event) { - event.preventDefault() - event.stopPropagation() - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var $menu = $li.find('.sharingOptionsGroup .popovermenu') - var shareId = $li.data('share-id') - - OC.showMenu(null, $menu) - - // focus the password if not set and enforced - var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true - var haspassword = $menu.find('.linkPassText').val() !== '' - - if (!haspassword && isPasswordEnabledByDefault) { - $menu.find('.linkPassText').focus() - } - }, - - /** - * @returns {Function} from Handlebars - * @private - */ - template: function() { - return OC.Share.Templates['sharedialoglinkshareview'] - }, - - /** - * renders the popover template and returns the resulting HTML - * - * @param {Object} data - * @returns {string} - */ - popoverMenuTemplate: function(data) { - return OC.Share.Templates['sharedialoglinkshareview_popover_menu'](data) - }, - - /** - * renders the pending popover template and returns the resulting HTML - * - * @param {Object} data - * @returns {string} - */ - pendingPopoverMenuTemplate: function(data) { - return OC.Share.Templates['sharedialoglinkshareview_popover_menu_pending'](data) - }, - - onPopUpClick: function(event) { - event.preventDefault() - event.stopPropagation() - - var url = $(event.currentTarget).data('url') - var newWindow = $(event.currentTarget).data('window') - $(event.currentTarget).tooltip('hide') - if (url) { - if (newWindow === true) { - var width = 600 - var height = 400 - var left = (screen.width / 2) - (width / 2) - var top = (screen.height / 2) - (height / 2) - - window.open(url, 'name', 'width=' + width + ', height=' + height + ', top=' + top + ', left=' + left) - } else { - window.location.href = url - } - } - }, - - onExpireDateChange: function(event) { - var $element = $(event.target) - var li = $element.closest('li[data-share-id]') - var shareId = li.data('share-id') - var expirationDatePicker = '#expirationDateContainer-' + shareId - var datePicker = $(expirationDatePicker) - var state = $element.prop('checked') - datePicker.toggleClass('hidden', !state) - - if (!state) { - // disabled, let's hide the input and - // set the expireDate to nothing - $element.closest('li').next('li').addClass('hidden') - this.setExpirationDate('', shareId) - } else { - // enabled, show the input and the datepicker - $element.closest('li').next('li').removeClass('hidden') - this.showDatePicker(event) - - } - }, - - showDatePicker: function(event) { - var $element = $(event.target) - var li = $element.closest('li[data-share-id]') - var shareId = li.data('share-id') - var maxDate = $element.data('max-date') - var expirationDatePicker = '#expirationDatePicker-' + shareId - var self = this - - $(expirationDatePicker).datepicker({ - dateFormat: 'dd-mm-yy', - onSelect: function(expireDate) { - self.setExpirationDate(expireDate, shareId) - }, - maxDate: maxDate - }) - $(expirationDatePicker).datepicker('show') - $(expirationDatePicker).focus() - - }, - - setExpirationDate: function(expireDate, shareId) { - this.model.saveLinkShare({ expireDate: expireDate, cid: shareId }) - }, - - onChangeExpirationDate: function(event) { - var $element = $(event.target) - var expireDate = $element.val() - var li = $element.closest('li[data-share-id]') - var shareId = li.data('share-id') - var expirationDatePicker = '#expirationDatePicker-' + shareId - - this.setExpirationDate(expireDate, shareId) - $(expirationDatePicker).datepicker('hide') - }, - - /** - * get an array of sharees' share properties - * - * @returns {Array} - */ - getShareeList: function() { - var shares = this.model.get('linkShares') - - if (!this.model.hasLinkShares()) { - return [] - } - - var list = [] - for (var index = 0; index < shares.length; index++) { - var share = this.getShareeObject(index) - // first empty {} is necessary, otherwise we get in trouble - // with references - list.push(_.extend({}, share)) - } - - return list - }, - - /** - * - * @param {OC.Share.Types.ShareInfo} shareInfo - * @returns {object} - */ - getShareeObject: function(shareIndex) { - var share = this.model.get('linkShares')[shareIndex] - - return _.extend({}, share, { - cid: share.id, - shareAllowed: true, - linkShareLabel: share.label ? share.label : t('core', 'Share link'), - popoverMenu: {}, - shareLinkURL: share.url, - newShareTitle: t('core', 'New share link'), - copyLabel: t('core', 'Copy link'), - showPending: this.showPending === share.id, - linkShareCreationDate: t('core', 'Created on {time}', { time: moment(share.stime * 1000).format('LLLL') }) - }) - }, - - getPopoverObject: function(share) { - var publicUploadRWChecked = '' - var publicUploadRChecked = '' - var publicUploadWChecked = '' - - switch (this.model.linkSharePermissions(share.id)) { - case OC.PERMISSION_READ: - publicUploadRChecked = 'checked' - break - case OC.PERMISSION_CREATE: - publicUploadWChecked = 'checked' - break - case OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE: - publicUploadRWChecked = 'checked' - break - } - - var isPasswordSet = !!share.password - var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true - var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink') - var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced') - var defaultExpireDays = this.configModel.get('defaultExpireDate') - var hasExpireDate = !!share.expiration || isExpirationEnforced - - var expireDate - if (hasExpireDate) { - expireDate = moment(share.expiration, 'YYYY-MM-DD').format('DD-MM-YYYY') - } - - var isTalkEnabled = OC.appswebroots['spreed'] !== undefined - var sendPasswordByTalk = share.sendPasswordByTalk - - var hideDownload = share.hideDownload - - var maxDate = null - - if (hasExpireDate) { - if (isExpirationEnforced) { - // TODO: hack: backend returns string instead of integer - var shareTime = share.stime - if (_.isNumber(shareTime)) { - shareTime = new Date(shareTime * 1000) - } - if (!shareTime) { - shareTime = new Date() // now - } - shareTime = OC.Util.stripTime(shareTime).getTime() - maxDate = new Date(shareTime + defaultExpireDays * 24 * 3600 * 1000) - } - } - - return { - cid: share.id, - shareLinkURL: share.url, - passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE, - isPasswordSet: isPasswordSet || isPasswordEnabledByDefault || isPasswordEnforced, - showPasswordByTalkCheckBox: isTalkEnabled && isPasswordSet, - passwordByTalkLabel: t('core', 'Password protect by Talk'), - isPasswordByTalkSet: sendPasswordByTalk, - publicUploadRWChecked: publicUploadRWChecked, - publicUploadRChecked: publicUploadRChecked, - publicUploadWChecked: publicUploadWChecked, - hasExpireDate: hasExpireDate, - expireDate: expireDate, - shareNote: share.note, - hasNote: share.note !== '', - maxDate: maxDate, - hideDownload: hideDownload, - isExpirationEnforced: isExpirationEnforced - } - }, - - onUnshare: function(event) { - event.preventDefault() - event.stopPropagation() - var self = this - var $element = $(event.target) - if (!$element.is('a')) { - $element = $element.closest('a') - } - - var $loading = $element.find('.icon-loading-small').eq(0) - if (!$loading.hasClass('hidden')) { - // in process - return false - } - $loading.removeClass('hidden') - - var $li = $element.closest('li[data-share-id]') - - var shareId = $li.data('share-id') - - self.model.removeShare(shareId, { - success: function() { - $li.remove() - self.render() - }, - error: function() { - $loading.addClass('hidden') - OC.Notification.showTemporary(t('core', 'Could not unshare')) - } - }) - return false - } - - }) - - OC.Share.ShareDialogLinkShareView = ShareDialogLinkShareView - -})() diff --git a/core/js/sharedialogresharerinfoview.js b/core/js/sharedialogresharerinfoview.js deleted file mode 100644 index b235adf435253571ddd132fa7895bc7084ce3a78..0000000000000000000000000000000000000000 --- a/core/js/sharedialogresharerinfoview.js +++ /dev/null @@ -1,159 +0,0 @@ -/* eslint-disable */ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* globals Handlebars */ - -(function() { - if (!OC.Share) { - OC.Share = {} - } - - /** - * @class OCA.Share.ShareDialogView - * @member {OC.Share.ShareItemModel} model - * @member {jQuery} $el - * @memberof OCA.Sharing - * @classdesc - * - * Represents the GUI of the share dialogue - * - */ - var ShareDialogResharerInfoView = OC.Backbone.View.extend({ - /** @type {string} **/ - id: 'shareDialogResharerInfo', - - /** @type {string} **/ - tagName: 'div', - - /** @type {string} **/ - className: 'reshare', - - /** @type {OC.Share.ShareConfigModel} **/ - configModel: undefined, - - /** @type {Function} **/ - _template: undefined, - - initialize: function(options) { - var view = this - - this.model.on('change:reshare', function() { - view.render() - }) - - if (!_.isUndefined(options.configModel)) { - this.configModel = options.configModel - } else { - throw 'missing OC.Share.ShareConfigModel' - } - }, - - render: function() { - if (!this.model.hasReshare() - || this.model.getReshareOwner() === OC.currentUser) { - this.$el.empty() - return this - } - - var reshareTemplate = this.template() - var ownerDisplayName = this.model.getReshareOwnerDisplayname() - var shareNote = this.model.getReshareNote() - - var sharedByText = '' - - if (this.model.getReshareType() === OC.Share.SHARE_TYPE_GROUP) { - sharedByText = t( - 'core', - 'Shared with you and the group {group} by {owner}', - { - group: this.model.getReshareWithDisplayName(), - owner: ownerDisplayName - }, - undefined, - { escape: false } - ) - } else if (this.model.getReshareType() === OC.Share.SHARE_TYPE_CIRCLE) { - sharedByText = t( - 'core', - 'Shared with you and {circle} by {owner}', - { - circle: this.model.getReshareWithDisplayName(), - owner: ownerDisplayName - }, - undefined, - { escape: false } - ) - } else if (this.model.getReshareType() === OC.Share.SHARE_TYPE_ROOM) { - if (this.model.get('reshare').share_with_displayname) { - sharedByText = t( - 'core', - 'Shared with you and the conversation {conversation} by {owner}', - { - conversation: this.model.getReshareWithDisplayName(), - owner: ownerDisplayName - }, - undefined, - { escape: false } - ) - } else { - sharedByText = t( - 'core', - 'Shared with you in a conversation by {owner}', - { - owner: ownerDisplayName - }, - undefined, - { escape: false } - ) - } - } else { - sharedByText = t( - 'core', - 'Shared with you by {owner}', - { owner: ownerDisplayName }, - undefined, - { escape: false } - ) - } - - this.$el.html(reshareTemplate({ - reshareOwner: this.model.getReshareOwner(), - sharedByText: sharedByText, - shareNote: shareNote, - hasShareNote: shareNote !== '' - })) - - this.$el.find('.avatar').each(function() { - var $this = $(this) - $this.avatar($this.data('username'), 32) - }) - - this.$el.find('.reshare').contactsMenu( - this.model.getReshareOwner(), - OC.Share.SHARE_TYPE_USER, - this.$el) - - return this - }, - - /** - * @returns {Function} from Handlebars - * @private - */ - template: function() { - return OC.Share.Templates['sharedialogresharerinfoview'] - } - - }) - - OC.Share.ShareDialogResharerInfoView = ShareDialogResharerInfoView - -})() diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js deleted file mode 100644 index 5fdb352fd50a4cb53afb0c166df03867c6872ca3..0000000000000000000000000000000000000000 --- a/core/js/sharedialogshareelistview.js +++ /dev/null @@ -1,777 +0,0 @@ -/* eslint-disable */ -/* global OC, Handlebars */ - -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* globals Handlebars */ - -(function() { - - var PASSWORD_PLACEHOLDER = '**********' - var PASSWORD_PLACEHOLDER_MESSAGE = t('core', 'Choose a password for the mail share') - - if (!OC.Share) { - OC.Share = {} - } - - /** - * @class OCA.Share.ShareDialogShareeListView - * @member {OC.Share.ShareItemModel} model - * @member {jQuery} $el - * @memberof OCA.Sharing - * @classdesc - * - * Represents the sharee list part in the GUI of the share dialogue - * - */ - var ShareDialogShareeListView = OC.Backbone.View.extend({ - /** @type {string} **/ - id: 'shareDialogLinkShare', - - /** @type {OC.Share.ShareConfigModel} **/ - configModel: undefined, - - _menuOpen: false, - - /** @type {boolean|number} **/ - _renderPermissionChange: false, - - events: { - 'click .unshare': 'onUnshare', - 'click .share-add': 'showNoteForm', - 'click .share-note-delete': 'deleteNote', - 'click .share-note-submit': 'updateNote', - 'click .share-menu .icon-more': 'onToggleMenu', - 'click .permissions': 'onPermissionChange', - 'click .expireDate': 'onExpireDateChange', - 'click .password': 'onMailSharePasswordProtectChange', - 'click .passwordByTalk': 'onMailSharePasswordProtectByTalkChange', - 'click .secureDrop': 'onSecureDropChange', - 'keyup input.passwordField': 'onMailSharePasswordKeyUp', - 'focusout input.passwordField': 'onMailSharePasswordEntered', - 'change .datepicker': 'onChangeExpirationDate', - 'click .datepicker': 'showDatePicker' - }, - - initialize: function(options) { - if (!_.isUndefined(options.configModel)) { - this.configModel = options.configModel - } else { - throw 'missing OC.Share.ShareConfigModel' - } - - var view = this - this.model.on('change:shares', function() { - view.render() - }) - }, - - /** - * - * @param {OC.Share.Types.ShareInfo} shareInfo - * @returns {object} - */ - getShareeObject: function(shareIndex) { - var shareWith = this.model.getShareWith(shareIndex) - var shareWithDisplayName = this.model.getShareWithDisplayName(shareIndex) - var shareWithAvatar = this.model.getShareWithAvatar(shareIndex) - var shareWithTitle = '' - var shareType = this.model.getShareType(shareIndex) - var sharedBy = this.model.getSharedBy(shareIndex) - var sharedByDisplayName = this.model.getSharedByDisplayName(shareIndex) - var fileOwnerUid = this.model.getFileOwnerUid(shareIndex) - - var hasPermissionOverride = {} - if (shareType === OC.Share.SHARE_TYPE_GROUP) { - shareWithDisplayName = shareWithDisplayName + ' (' + t('core', 'group') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_REMOTE) { - shareWithDisplayName = shareWithDisplayName + ' (' + t('core', 'remote') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP) { - shareWithDisplayName = shareWithDisplayName + ' (' + t('core', 'remote group') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_EMAIL) { - shareWithDisplayName = shareWithDisplayName + ' (' + t('core', 'email') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_CIRCLE) { - } else if (shareType === OC.Share.SHARE_TYPE_ROOM) { - shareWithDisplayName = shareWithDisplayName + ' (' + t('core', 'conversation') + ')' - } - - if (shareType === OC.Share.SHARE_TYPE_GROUP) { - shareWithTitle = shareWith + ' (' + t('core', 'group') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_REMOTE) { - shareWithTitle = shareWith + ' (' + t('core', 'remote') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP) { - shareWithTitle = shareWith + ' (' + t('core', 'remote group') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_EMAIL) { - shareWithTitle = shareWith + ' (' + t('core', 'email') + ')' - } else if (shareType === OC.Share.SHARE_TYPE_CIRCLE) { - shareWithTitle = shareWith - // Force "shareWith" in the template to a safe value, as the - // original "shareWith" returned by the model may contain - // problematic characters like "'". - shareWith = 'circle-' + shareIndex - } - - if (sharedBy !== OC.getCurrentUser().uid) { - var empty = shareWithTitle === '' - if (!empty) { - shareWithTitle += ' (' - } - shareWithTitle += t('core', 'shared by {sharer}', { sharer: sharedByDisplayName }) - if (!empty) { - shareWithTitle += ')' - } - } - - var share = this.model.get('shares')[shareIndex] - var password = share.password - var hasPassword = password !== null && password !== '' - var sendPasswordByTalk = share.send_password_by_talk - - var shareNote = this.model.getNote(shareIndex) - - return _.extend(hasPermissionOverride, { - cid: this.cid, - hasSharePermission: this.model.hasSharePermission(shareIndex), - editPermissionState: this.model.editPermissionState(shareIndex), - hasCreatePermission: this.model.hasCreatePermission(shareIndex), - hasUpdatePermission: this.model.hasUpdatePermission(shareIndex), - hasDeletePermission: this.model.hasDeletePermission(shareIndex), - sharedBy: sharedBy, - sharedByDisplayName: sharedByDisplayName, - shareWith: shareWith, - shareWithDisplayName: shareWithDisplayName, - shareWithAvatar: shareWithAvatar, - shareWithTitle: shareWithTitle, - shareType: shareType, - shareId: this.model.get('shares')[shareIndex].id, - modSeed: shareWithAvatar || (shareType !== OC.Share.SHARE_TYPE_USER && shareType !== OC.Share.SHARE_TYPE_CIRCLE && shareType !== OC.Share.SHARE_TYPE_ROOM), - owner: fileOwnerUid, - isShareWithCurrentUser: (shareType === OC.Share.SHARE_TYPE_USER && shareWith === OC.getCurrentUser().uid), - canUpdateShareSettings: (sharedBy === OC.getCurrentUser().uid || fileOwnerUid === OC.getCurrentUser().uid), - isRemoteShare: shareType === OC.Share.SHARE_TYPE_REMOTE, - isRemoteGroupShare: shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP, - isNoteAvailable: shareType !== OC.Share.SHARE_TYPE_REMOTE && shareType !== OC.Share.SHARE_TYPE_REMOTE_GROUP, - isMailShare: shareType === OC.Share.SHARE_TYPE_EMAIL, - isCircleShare: shareType === OC.Share.SHARE_TYPE_CIRCLE, - isFileSharedByMail: shareType === OC.Share.SHARE_TYPE_EMAIL && !this.model.isFolder(), - isPasswordSet: hasPassword && !sendPasswordByTalk, - isPasswordByTalkSet: hasPassword && sendPasswordByTalk, - isTalkEnabled: OC.appswebroots['spreed'] !== undefined, - secureDropMode: !this.model.hasReadPermission(shareIndex), - hasExpireDate: this.model.getExpireDate(shareIndex) !== null, - shareNote: shareNote, - hasNote: shareNote !== '', - expireDate: moment(this.model.getExpireDate(shareIndex), 'YYYY-MM-DD').format('DD-MM-YYYY'), - // The password placeholder does not take into account if - // sending the password by Talk is enabled or not; when - // switching from sending the password by Talk to sending the - // password by email the password is reused and the share - // updated, so the placeholder already shows the password in the - // brief time between disabling sending the password by email - // and receiving the updated share. - passwordPlaceholder: hasPassword ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE, - passwordByTalkPlaceholder: (hasPassword && sendPasswordByTalk) ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE - }) - }, - - getShareProperties: function() { - return { - unshareLabel: t('core', 'Unshare'), - addNoteLabel: t('core', 'Note to recipient'), - canShareLabel: t('core', 'Can reshare'), - canEditLabel: t('core', 'Can edit'), - createPermissionLabel: t('core', 'Can create'), - updatePermissionLabel: t('core', 'Can change'), - deletePermissionLabel: t('core', 'Can delete'), - secureDropLabel: t('core', 'File drop (upload only)'), - expireDateLabel: t('core', 'Set expiration date'), - passwordLabel: t('core', 'Password protect'), - passwordByTalkLabel: t('core', 'Password protect by Talk'), - crudsLabel: t('core', 'Access control'), - expirationDatePlaceholder: t('core', 'Expiration date'), - defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today - triangleSImage: OC.imagePath('core', 'actions/triangle-s'), - isResharingAllowed: this.configModel.get('isResharingAllowed'), - isPasswordForMailSharesRequired: this.configModel.get('isPasswordForMailSharesRequired'), - sharePermissionPossible: this.model.sharePermissionPossible(), - editPermissionPossible: this.model.editPermissionPossible(), - createPermissionPossible: this.model.createPermissionPossible(), - updatePermissionPossible: this.model.updatePermissionPossible(), - deletePermissionPossible: this.model.deletePermissionPossible(), - sharePermission: OC.PERMISSION_SHARE, - createPermission: OC.PERMISSION_CREATE, - updatePermission: OC.PERMISSION_UPDATE, - deletePermission: OC.PERMISSION_DELETE, - readPermission: OC.PERMISSION_READ, - isFolder: this.model.isFolder() - } - }, - - /** - * get an array of sharees' share properties - * - * @returns {Array} - */ - getShareeList: function() { - var universal = this.getShareProperties() - - if (!this.model.hasUserShares()) { - return [] - } - - var shares = this.model.get('shares') - var list = [] - for (var index = 0; index < shares.length; index++) { - var share = this.getShareeObject(index) - - if (share.shareType === OC.Share.SHARE_TYPE_LINK) { - continue - } - // first empty {} is necessary, otherwise we get in trouble - // with references - list.push(_.extend({}, universal, share)) - } - - return list - }, - - getLinkReshares: function() { - var universal = { - unshareLabel: t('core', 'Unshare') - } - - if (!this.model.hasUserShares()) { - return [] - } - - var shares = this.model.get('shares') - var list = [] - for (var index = 0; index < shares.length; index++) { - var share = this.getShareeObject(index) - - if (share.shareType !== OC.Share.SHARE_TYPE_LINK) { - continue - } - // first empty {} is necessary, otherwise we get in trouble - // with references - list.push(_.extend({}, universal, share, { - shareInitiator: shares[index].uid_owner, - shareInitiatorText: t('core', '{shareInitiatorDisplayName} shared via link', { shareInitiatorDisplayName: shares[index].displayname_owner }) - })) - } - - return list - }, - - render: function() { - if (!this._renderPermissionChange) { - this.$el.html(this.template({ - cid: this.cid, - sharees: this.getShareeList(), - linkReshares: this.getLinkReshares() - })) - - this.$('.avatar').each(function() { - var $this = $(this) - - if ($this.hasClass('imageplaceholderseed')) { - $this.css({ width: 32, height: 32 }) - if ($this.data('avatar')) { - $this.css('border-radius', '0%') - $this.css('background', 'url(' + $this.data('avatar') + ') no-repeat') - $this.css('background-size', '31px') - } else { - $this.imageplaceholder($this.data('seed')) - } - } else { - // user, size, ie8fix, hidedefault, callback, displayname - $this.avatar($this.data('username'), 32, undefined, undefined, undefined, $this.data('displayname')) - } - }) - - this.$('.has-tooltip').tooltip({ - placement: 'bottom' - }) - - this.$('ul.shareWithList > li').each(function() { - var $this = $(this) - - var shareWith = $this.data('share-with') - var shareType = $this.data('share-type') - - $this.find('div.avatar, span.username').contactsMenu(shareWith, shareType, $this) - }) - } else { - var permissionChangeShareId = parseInt(this._renderPermissionChange, 10) - var shareWithIndex = this.model.findShareWithIndex(permissionChangeShareId) - var sharee = this.getShareeObject(shareWithIndex) - $.extend(sharee, this.getShareProperties()) - var $li = this.$('li[data-share-id=' + permissionChangeShareId + ']') - $li.find('.sharingOptionsGroup .popovermenu').replaceWith(this.popoverMenuTemplate(sharee)) - } - - var _this = this - this.getShareeList().forEach(function(sharee) { - var $edit = _this.$('#canEdit-' + _this.cid + '-' + sharee.shareId) - if ($edit.length === 1) { - $edit.prop('checked', sharee.editPermissionState === 'checked') - if (sharee.isFolder) { - $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate') - } - } - }) - this.$('.popovermenu').on('afterHide', function() { - _this._menuOpen = false - }) - this.$('.popovermenu').on('beforeHide', function() { - var shareId = parseInt(_this._menuOpen, 10) - if (!_.isNaN(shareId)) { - var datePickerClass = '.expirationDateContainer-' + _this.cid + '-' + shareId - var datePickerInput = '#expirationDatePicker-' + _this.cid + '-' + shareId - var expireDateCheckbox = '#expireDate-' + _this.cid + '-' + shareId - if ($(expireDateCheckbox).prop('checked')) { - $(datePickerInput).removeClass('hidden-visually') - $(datePickerClass).removeClass('hasDatepicker') - $(datePickerClass + ' .ui-datepicker').hide() - } - } - }) - if (this._menuOpen !== false) { - // Open menu again if it was opened before - var shareId = parseInt(this._menuOpen, 10) - if (!_.isNaN(shareId)) { - var liSelector = 'li[data-share-id=' + shareId + ']' - OC.showMenu(null, this.$(liSelector + ' .sharingOptionsGroup .popovermenu')) - } - } - - this._renderPermissionChange = false - - // new note autosize - autosize(this.$el.find('.share-note-form .share-note')) - - this.delegateEvents() - - return this - }, - - /** - * @returns {Function} from Handlebars - * @private - */ - template: function(data) { - var sharees = data.sharees - if (_.isArray(sharees)) { - for (var i = 0; i < sharees.length; i++) { - data.sharees[i].popoverMenu = this.popoverMenuTemplate(sharees[i]) - } - } - return OC.Share.Templates['sharedialogshareelistview'](data) - }, - - /** - * renders the popover template and returns the resulting HTML - * - * @param {Object} data - * @returns {string} - */ - popoverMenuTemplate: function(data) { - return OC.Share.Templates['sharedialogshareelistview_popover_menu'](data) - }, - - showNoteForm: function(event) { - event.preventDefault() - event.stopPropagation() - var $element = $(event.target) - var $menu = $element.closest('li') - var $form = $menu.next('li.share-note-form') - - // show elements - $menu.find('.share-note-delete').toggleClass('hidden') - $form.toggleClass('hidden') - $form.find('textarea').focus() - }, - - deleteNote: function(event) { - event.preventDefault() - event.stopPropagation() - var self = this - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $menu = $element.closest('li') - var $form = $menu.next('li.share-note-form') - - console.log($form.find('.share-note')) - $form.find('.share-note').val('') - - $form.addClass('hidden') - $menu.find('.share-note-delete').addClass('hidden') - - self.sendNote('', shareId, $menu) - }, - - updateNote: function(event) { - event.preventDefault() - event.stopPropagation() - var self = this - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - var $form = $element.closest('li.share-note-form') - var $menu = $form.prev('li') - var message = $form.find('.share-note').val().trim() - - if (message.length < 1) { - return - } - - self.sendNote(message, shareId, $menu) - - }, - - sendNote: function(note, shareId, $menu) { - var $form = $menu.next('li.share-note-form') - var $submit = $form.find('input.share-note-submit') - var $error = $form.find('input.share-note-error') - - $submit.prop('disabled', true) - $menu.find('.icon-loading-small').removeClass('hidden') - $menu.find('.icon-edit').hide() - - var complete = function() { - $submit.prop('disabled', false) - $menu.find('.icon-loading-small').addClass('hidden') - $menu.find('.icon-edit').show() - } - var error = function() { - $error.show() - setTimeout(function() { - $error.hide() - }, 3000) - } - - // send data - $.ajax({ - method: 'PUT', - url: OC.linkToOCS('apps/files_sharing/api/v1/shares', 2) + shareId + '?' + OC.buildQueryString({ format: 'json' }), - data: { note: note }, - complete: complete, - error: error - }) - }, - - onUnshare: function(event) { - event.preventDefault() - event.stopPropagation() - var self = this - var $element = $(event.target) - if (!$element.is('a')) { - $element = $element.closest('a') - } - - var $loading = $element.find('.icon-loading-small').eq(0) - if (!$loading.hasClass('hidden')) { - // in process - return false - } - $loading.removeClass('hidden') - - var $li = $element.closest('li[data-share-id]') - - var shareId = $li.data('share-id') - - self.model.removeShare(shareId) - .done(function() { - $li.remove() - }) - .fail(function() { - $loading.addClass('hidden') - OC.Notification.showTemporary(t('core', 'Could not unshare')) - }) - return false - }, - - onToggleMenu: function(event) { - event.preventDefault() - event.stopPropagation() - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var $menu = $li.find('.sharingOptionsGroup .popovermenu') - - OC.showMenu(null, $menu) - this._menuOpen = $li.data('share-id') - }, - - onExpireDateChange: function(event) { - var $element = $(event.target) - var li = $element.closest('li[data-share-id]') - var shareId = li.data('share-id') - var datePickerClass = '.expirationDateContainer-' + this.cid + '-' + shareId - var datePicker = $(datePickerClass) - var state = $element.prop('checked') - datePicker.toggleClass('hidden', !state) - if (!state) { - // disabled, let's hide the input and - // set the expireDate to nothing - $element.closest('li').next('li').addClass('hidden') - this.setExpirationDate(shareId, '') - } else { - // enabled, show the input and the datepicker - $element.closest('li').next('li').removeClass('hidden') - this.showDatePicker(event) - - } - }, - - showDatePicker: function(event) { - var element = $(event.target) - var li = element.closest('li[data-share-id]') - var shareId = li.data('share-id') - var expirationDatePicker = '#expirationDatePicker-' + this.cid + '-' + shareId - var view = this - $(expirationDatePicker).datepicker({ - dateFormat: 'dd-mm-yy', - onSelect: function(expireDate) { - view.setExpirationDate(shareId, expireDate) - } - }) - $(expirationDatePicker).focus() - - }, - - setExpirationDate: function(shareId, expireDate) { - this.model.updateShare(shareId, { expireDate: expireDate }, {}) - }, - - onMailSharePasswordProtectChange: function(event) { - var element = $(event.target) - var li = element.closest('li[data-share-id]') - var shareId = li.data('share-id') - var passwordContainerClass = '.passwordMenu-' + this.cid + '-' + shareId - var passwordContainer = $(passwordContainerClass) - var loading = this.$el.find(passwordContainerClass + ' .icon-loading-small') - var inputClass = '#passwordField-' + this.cid + '-' + shareId - var passwordField = $(inputClass) - var state = element.prop('checked') - var passwordByTalkElement = $('#passwordByTalk-' + this.cid + '-' + shareId) - var passwordByTalkState = passwordByTalkElement.prop('checked') - if (!state && !passwordByTalkState) { - this.model.updateShare(shareId, { password: '', sendPasswordByTalk: false }) - passwordField.attr('value', '') - passwordField.removeClass('error') - passwordField.tooltip('hide') - loading.addClass('hidden') - passwordField.attr('placeholder', PASSWORD_PLACEHOLDER_MESSAGE) - // We first need to reset the password field before we hide it - passwordContainer.toggleClass('hidden', !state) - } else if (state) { - if (passwordByTalkState) { - // Switching from sending the password by Talk to sending - // the password by mail can be done keeping the previous - // password sent by Talk. - this.model.updateShare(shareId, { sendPasswordByTalk: false }) - - var passwordByTalkContainerClass = '.passwordByTalkMenu-' + this.cid + '-' + shareId - var passwordByTalkContainer = $(passwordByTalkContainerClass) - passwordByTalkContainer.addClass('hidden') - passwordByTalkElement.prop('checked', false) - } - - passwordContainer.toggleClass('hidden', !state) - passwordField = '#passwordField-' + this.cid + '-' + shareId - this.$(passwordField).focus() - } - }, - - onMailSharePasswordProtectByTalkChange: function(event) { - var element = $(event.target) - var li = element.closest('li[data-share-id]') - var shareId = li.data('share-id') - var passwordByTalkContainerClass = '.passwordByTalkMenu-' + this.cid + '-' + shareId - var passwordByTalkContainer = $(passwordByTalkContainerClass) - var loading = this.$el.find(passwordByTalkContainerClass + ' .icon-loading-small') - var inputClass = '#passwordByTalkField-' + this.cid + '-' + shareId - var passwordByTalkField = $(inputClass) - var state = element.prop('checked') - var passwordElement = $('#password-' + this.cid + '-' + shareId) - var passwordState = passwordElement.prop('checked') - if (!state) { - this.model.updateShare(shareId, { password: '', sendPasswordByTalk: false }) - passwordByTalkField.attr('value', '') - passwordByTalkField.removeClass('error') - passwordByTalkField.tooltip('hide') - loading.addClass('hidden') - passwordByTalkField.attr('placeholder', PASSWORD_PLACEHOLDER_MESSAGE) - // We first need to reset the password field before we hide it - passwordByTalkContainer.toggleClass('hidden', !state) - } else if (state) { - if (passwordState) { - // Enabling sending the password by Talk requires a new - // password to be given (the one sent by mail is not reused, - // as it would defeat the purpose of checking the identity - // of the sharee by Talk if it was already sent by mail), so - // the share is not updated until the user explicitly gives - // the new password. - - var passwordContainerClass = '.passwordMenu-' + this.cid + '-' + shareId - var passwordContainer = $(passwordContainerClass) - passwordContainer.addClass('hidden') - passwordElement.prop('checked', false) - } - - passwordByTalkContainer.toggleClass('hidden', !state) - passwordByTalkField = '#passwordByTalkField-' + this.cid + '-' + shareId - this.$(passwordByTalkField).focus() - } - }, - - onMailSharePasswordKeyUp: function(event) { - if (event.keyCode === 13) { - this.onMailSharePasswordEntered(event) - } - }, - - onMailSharePasswordEntered: function(event) { - var passwordField = $(event.target) - var li = passwordField.closest('li[data-share-id]') - var shareId = li.data('share-id') - var passwordContainerClass = '.passwordMenu-' + this.cid + '-' + shareId - var passwordByTalkContainerClass = '.passwordByTalkMenu-' + this.cid + '-' + shareId - var sendPasswordByTalk = passwordField.attr('id').startsWith('passwordByTalk') - var loading - if (sendPasswordByTalk) { - loading = this.$el.find(passwordByTalkContainerClass + ' .icon-loading-small') - } else { - loading = this.$el.find(passwordContainerClass + ' .icon-loading-small') - } - if (!loading.hasClass('hidden')) { - // still in process - return - } - - passwordField.removeClass('error') - var password = passwordField.val() - // in IE9 the password might be the placeholder due to bugs in the placeholders polyfill - if (password === '' || password === PASSWORD_PLACEHOLDER || password === PASSWORD_PLACEHOLDER_MESSAGE) { - return - } - - loading - .removeClass('hidden') - .addClass('inlineblock') - - this.model.updateShare(shareId, { - password: password, - sendPasswordByTalk: sendPasswordByTalk - }, { - error: function(model, msg) { - // destroy old tooltips - passwordField.tooltip('destroy') - loading.removeClass('inlineblock').addClass('hidden') - passwordField.addClass('error') - passwordField.attr('title', msg) - passwordField.tooltip({ placement: 'bottom', trigger: 'manual' }) - passwordField.tooltip('show') - }, - success: function(model, msg) { - passwordField.blur() - passwordField.attr('value', '') - passwordField.attr('placeholder', PASSWORD_PLACEHOLDER) - loading.removeClass('inlineblock').addClass('hidden') - } - }) - }, - - onPermissionChange: function(event) { - event.preventDefault() - event.stopPropagation() - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - - var permissions = OC.PERMISSION_READ - - if (this.model.isFolder()) { - // adjust checkbox states - var $checkboxes = $('.permissions', $li).not('input[name="edit"]').not('input[name="share"]') - var checked - if ($element.attr('name') === 'edit') { - checked = $element.is(':checked') - // Check/uncheck Create, Update, and Delete checkboxes if Edit is checked/unck - $($checkboxes).prop('checked', checked) - if (checked) { - permissions |= OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE - } - } else { - var numberChecked = $checkboxes.filter(':checked').length - checked = numberChecked === $checkboxes.length - var $editCb = $('input[name="edit"]', $li) - $editCb.prop('checked', checked) - $editCb.prop('indeterminate', !checked && numberChecked > 0) - } - } else { - if ($element.attr('name') === 'edit' && $element.is(':checked')) { - permissions |= OC.PERMISSION_UPDATE - } - } - - $('.permissions', $li).not('input[name="edit"]').filter(':checked').each(function(index, checkbox) { - permissions |= $(checkbox).data('permissions') - }) - - /** disable checkboxes during save operation to avoid race conditions **/ - $li.find('input[type=checkbox]').prop('disabled', true) - var enableCb = function() { - $li.find('input[type=checkbox]').prop('disabled', false) - } - var errorCb = function(elem, msg) { - OC.dialogs.alert(msg, t('core', 'Error while sharing')) - enableCb() - } - - this.model.updateShare(shareId, { permissions: permissions }, { error: errorCb, success: enableCb }) - - this._renderPermissionChange = shareId - }, - - onSecureDropChange: function(event) { - event.preventDefault() - event.stopPropagation() - var $element = $(event.target) - var $li = $element.closest('li[data-share-id]') - var shareId = $li.data('share-id') - - var permissions = OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE | OC.PERMISSION_READ - if ($element.is(':checked')) { - permissions = OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE - } - - /** disable checkboxes during save operation to avoid race conditions **/ - $li.find('input[type=checkbox]').prop('disabled', true) - var enableCb = function() { - $li.find('input[type=checkbox]').prop('disabled', false) - } - var errorCb = function(elem, msg) { - OC.dialogs.alert(msg, t('core', 'Error while sharing')) - enableCb() - } - - this.model.updateShare(shareId, { permissions: permissions }, { error: errorCb, success: enableCb }) - - this._renderPermissionChange = shareId - } - - }) - - OC.Share.ShareDialogShareeListView = ShareDialogShareeListView - -})() diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js deleted file mode 100644 index 9bc87a69463869f2eb1bc58181805f72cc85cbd1..0000000000000000000000000000000000000000 --- a/core/js/sharedialogview.js +++ /dev/null @@ -1,1137 +0,0 @@ -/* eslint-disable */ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -/* globals Handlebars */ - -(function() { - if (!OC.Share) { - OC.Share = {} - } - - /** - * @class OCA.Share.ShareDialogView - * @member {OC.Share.ShareItemModel} model - * @member {jQuery} $el - * @memberof OCA.Sharing - * @classdesc - * - * Represents the GUI of the share dialogue - * - */ - var ShareDialogView = OC.Backbone.View.extend({ - /** @type {Object} **/ - _templates: {}, - - /** @type {boolean} **/ - _showLink: true, - - _lookup: false, - - _lookupAllowed: false, - - /** @type {string} **/ - tagName: 'div', - - /** @type {OC.Share.ShareConfigModel} **/ - configModel: undefined, - - /** @type {object} **/ - resharerInfoView: undefined, - - /** @type {object} **/ - linkShareView: undefined, - - /** @type {object} **/ - shareeListView: undefined, - - /** @type {object} **/ - _lastSuggestions: undefined, - - /** @type {object} **/ - _lastRecommendations: undefined, - - /** @type {int} **/ - _pendingOperationsCount: 0, - - events: { - 'focus .shareWithField': 'onShareWithFieldFocus', - 'input .shareWithField': 'onShareWithFieldChanged', - 'click .shareWithConfirm': '_confirmShare' - }, - - initialize: function(options) { - var view = this - - this.model.on('fetchError', function() { - OC.Notification.showTemporary(t('core', 'Share details could not be loaded for this item.')) - }) - - if (!_.isUndefined(options.configModel)) { - this.configModel = options.configModel - } else { - throw 'missing OC.Share.ShareConfigModel' - } - - this.configModel.on('change:isRemoteShareAllowed', function() { - view.render() - }) - this.configModel.on('change:isRemoteGroupShareAllowed', function() { - view.render() - }) - this.model.on('change:permissions', function() { - view.render() - }) - - this.model.on('request', this._onRequest, this) - this.model.on('sync', this._onEndRequest, this) - - var subViewOptions = { - model: this.model, - configModel: this.configModel - } - - var subViews = { - resharerInfoView: 'ShareDialogResharerInfoView', - linkShareView: 'ShareDialogLinkShareView', - shareeListView: 'ShareDialogShareeListView' - } - - for (var name in subViews) { - var className = subViews[name] - this[name] = _.isUndefined(options[name]) - ? new OC.Share[className](subViewOptions) - : options[name] - } - - _.bindAll(this, - 'autocompleteHandler', - '_onSelectRecipient', - 'onShareWithFieldChanged', - 'onShareWithFieldFocus' - ) - - OC.Plugins.attach('OC.Share.ShareDialogView', this) - }, - - onShareWithFieldChanged: function() { - var $el = this.$el.find('.shareWithField') - if ($el.val().length < 2) { - $el.removeClass('error').tooltip('hide') - } - }, - - /* trigger search after the field was re-selected */ - onShareWithFieldFocus: function() { - var $shareWithField = this.$el.find('.shareWithField') - $shareWithField.autocomplete('search', $shareWithField.val()) - }, - - _getSuggestions: function(searchTerm, perPage, model, lookup) { - if (this._lastSuggestions - && this._lastSuggestions.searchTerm === searchTerm - && this._lastSuggestions.lookup === lookup - && this._lastSuggestions.perPage === perPage - && this._lastSuggestions.model === model) { - return this._lastSuggestions.promise - } - - var deferred = $.Deferred() - var view = this - - $.get( - OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees', - { - format: 'json', - search: searchTerm, - lookup: lookup, - perPage: perPage, - itemType: model.get('itemType') - }, - function(result) { - if (result.ocs.meta.statuscode === 100) { - var filter = function(users, groups, remotes, remote_groups, emails, circles, rooms) { - if (typeof (emails) === 'undefined') { - emails = [] - } - if (typeof (circles) === 'undefined') { - circles = [] - } - if (typeof (rooms) === 'undefined') { - rooms = [] - } - - var usersLength - var groupsLength - var remotesLength - var remoteGroupsLength - var emailsLength - var circlesLength - var roomsLength - - var i, j - - // Filter out the current user - usersLength = users.length - for (i = 0; i < usersLength; i++) { - if (users[i].value.shareWith === OC.currentUser) { - users.splice(i, 1) - break - } - } - - // Filter out the owner of the share - if (model.hasReshare()) { - usersLength = users.length - for (i = 0; i < usersLength; i++) { - if (users[i].value.shareWith === model.getReshareOwner()) { - users.splice(i, 1) - break - } - } - } - - var shares = model.get('shares') - var sharesLength = shares.length - - // Now filter out all sharees that are already shared with - for (i = 0; i < sharesLength; i++) { - var share = shares[i] - - if (share.share_type === OC.Share.SHARE_TYPE_USER) { - usersLength = users.length - for (j = 0; j < usersLength; j++) { - if (users[j].value.shareWith === share.share_with) { - users.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) { - groupsLength = groups.length - for (j = 0; j < groupsLength; j++) { - if (groups[j].value.shareWith === share.share_with) { - groups.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) { - remotesLength = remotes.length - for (j = 0; j < remotesLength; j++) { - if (remotes[j].value.shareWith === share.share_with) { - remotes.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE_GROUP) { - remoteGroupsLength = remote_groups.length - for (j = 0; j < remoteGroupsLength; j++) { - if (remote_groups[j].value.shareWith === share.share_with) { - remote_groups.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) { - emailsLength = emails.length - for (j = 0; j < emailsLength; j++) { - if (emails[j].value.shareWith === share.share_with) { - emails.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_CIRCLE) { - circlesLength = circles.length - for (j = 0; j < circlesLength; j++) { - if (circles[j].value.shareWith === share.share_with) { - circles.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_ROOM) { - roomsLength = rooms.length - for (j = 0; j < roomsLength; j++) { - if (rooms[j].value.shareWith === share.share_with) { - rooms.splice(j, 1) - break - } - } - } - } - } - - filter( - result.ocs.data.exact.users, - result.ocs.data.exact.groups, - result.ocs.data.exact.remotes, - result.ocs.data.exact.remote_groups, - result.ocs.data.exact.emails, - result.ocs.data.exact.circles, - result.ocs.data.exact.rooms - ) - - var exactUsers = result.ocs.data.exact.users - var exactGroups = result.ocs.data.exact.groups - var exactRemotes = result.ocs.data.exact.remotes - var exactRemoteGroups = result.ocs.data.exact.remote_groups - var exactEmails = [] - if (typeof (result.ocs.data.emails) !== 'undefined') { - exactEmails = result.ocs.data.exact.emails - } - var exactCircles = [] - if (typeof (result.ocs.data.circles) !== 'undefined') { - exactCircles = result.ocs.data.exact.circles - } - var exactRooms = [] - if (typeof (result.ocs.data.rooms) !== 'undefined') { - exactRooms = result.ocs.data.exact.rooms - } - - var exactMatches = exactUsers.concat(exactGroups).concat(exactRemotes).concat(exactRemoteGroups).concat(exactEmails).concat(exactCircles).concat(exactRooms) - - filter( - result.ocs.data.users, - result.ocs.data.groups, - result.ocs.data.remotes, - result.ocs.data.remote_groups, - result.ocs.data.emails, - result.ocs.data.circles, - result.ocs.data.rooms - ) - - var users = result.ocs.data.users - var groups = result.ocs.data.groups - var remotes = result.ocs.data.remotes - var remoteGroups = result.ocs.data.remote_groups - var lookup = result.ocs.data.lookup - var lookupEnabled = result.ocs.data.lookupEnabled - var emails = [] - if (typeof (result.ocs.data.emails) !== 'undefined') { - emails = result.ocs.data.emails - } - var circles = [] - if (typeof (result.ocs.data.circles) !== 'undefined') { - circles = result.ocs.data.circles - } - var rooms = [] - if (typeof (result.ocs.data.rooms) !== 'undefined') { - rooms = result.ocs.data.rooms - } - - var suggestions = exactMatches.concat(users).concat(groups).concat(remotes).concat(remoteGroups).concat(emails).concat(circles).concat(rooms).concat(lookup) - - function dynamicSort(property) { - return function(a, b) { - var aProperty = '' - var bProperty = '' - if (typeof a[property] !== 'undefined') { - aProperty = a[property] - } - if (typeof b[property] !== 'undefined') { - bProperty = b[property] - } - return (aProperty < bProperty) ? -1 : (aProperty > bProperty) ? 1 : 0 - } - } - - /** - * Sort share entries by uuid to properly group them - */ - var grouped = suggestions.sort(dynamicSort('uuid')) - - var previousUuid = null - var groupedLength = grouped.length - var result = [] - /** - * build the result array that only contains all contact entries from - * merged contacts, if the search term matches its contact name - */ - for (var i = 0; i < groupedLength; i++) { - if (typeof grouped[i].uuid !== 'undefined' && grouped[i].uuid === previousUuid) { - grouped[i].merged = true - } - if (searchTerm === grouped[i].name || typeof grouped[i].merged === 'undefined') { - result.push(grouped[i]) - } - previousUuid = grouped[i].uuid - } - var moreResultsAvailable - = ( - OC.config['sharing.maxAutocompleteResults'] > 0 - && Math.min(perPage, OC.config['sharing.maxAutocompleteResults']) - <= Math.max( - users.length + exactUsers.length, - groups.length + exactGroups.length, - remoteGroups.length + exactRemoteGroups.length, - remotes.length + exactRemotes.length, - emails.length + exactEmails.length, - circles.length + exactCircles.length, - rooms.length + exactRooms.length, - lookup.length - ) - ) - if (!view._lookup && lookupEnabled) { - result.push( - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - } - ) - } - - deferred.resolve(result, exactMatches, moreResultsAvailable, lookupEnabled) - } else { - deferred.reject(result.ocs.meta.message) - } - } - ).fail(function() { - deferred.reject() - }) - - this._lastSuggestions = { - searchTerm: searchTerm, - lookup: lookup, - perPage: perPage, - model: model, - promise: deferred.promise() - } - - return this._lastSuggestions.promise - }, - - _getRecommendations: function(model) { - if (this._lastRecommendations - && this._lastRecommendations.model === model) { - return this._lastRecommendations.promise - } - - var deferred = $.Deferred() - - $.get( - OC.linkToOCS('apps/files_sharing/api/v1') + 'sharees_recommended', - { - format: 'json', - itemType: model.get('itemType') - }, - function(result) { - if (result.ocs.meta.statuscode === 100) { - var filter = function(users, groups, remotes, remote_groups, emails, circles, rooms) { - if (typeof (emails) === 'undefined') { - emails = [] - } - if (typeof (circles) === 'undefined') { - circles = [] - } - if (typeof (rooms) === 'undefined') { - rooms = [] - } - - var usersLength - var groupsLength - var remotesLength - var remoteGroupsLength - var emailsLength - var circlesLength - var roomsLength - - var i, j - - // Filter out the current user - usersLength = users.length - for (i = 0; i < usersLength; i++) { - if (users[i].value.shareWith === OC.currentUser) { - users.splice(i, 1) - break - } - } - - // Filter out the owner of the share - if (model.hasReshare()) { - usersLength = users.length - for (i = 0; i < usersLength; i++) { - if (users[i].value.shareWith === model.getReshareOwner()) { - users.splice(i, 1) - break - } - } - } - - var shares = model.get('shares') - var sharesLength = shares.length - - // Now filter out all sharees that are already shared with - for (i = 0; i < sharesLength; i++) { - var share = shares[i] - - if (share.share_type === OC.Share.SHARE_TYPE_USER) { - usersLength = users.length - for (j = 0; j < usersLength; j++) { - if (users[j].value.shareWith === share.share_with) { - users.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_GROUP) { - groupsLength = groups.length - for (j = 0; j < groupsLength; j++) { - if (groups[j].value.shareWith === share.share_with) { - groups.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE) { - remotesLength = remotes.length - for (j = 0; j < remotesLength; j++) { - if (remotes[j].value.shareWith === share.share_with) { - remotes.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_REMOTE_GROUP) { - remoteGroupsLength = remote_groups.length - for (j = 0; j < remoteGroupsLength; j++) { - if (remote_groups[j].value.shareWith === share.share_with) { - remote_groups.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_EMAIL) { - emailsLength = emails.length - for (j = 0; j < emailsLength; j++) { - if (emails[j].value.shareWith === share.share_with) { - emails.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_CIRCLE) { - circlesLength = circles.length - for (j = 0; j < circlesLength; j++) { - if (circles[j].value.shareWith === share.share_with) { - circles.splice(j, 1) - break - } - } - } else if (share.share_type === OC.Share.SHARE_TYPE_ROOM) { - roomsLength = rooms.length - for (j = 0; j < roomsLength; j++) { - if (rooms[j].value.shareWith === share.share_with) { - rooms.splice(j, 1) - break - } - } - } - } - } - - filter( - result.ocs.data.exact.users, - result.ocs.data.exact.groups, - result.ocs.data.exact.remotes, - result.ocs.data.exact.remote_groups, - result.ocs.data.exact.emails, - result.ocs.data.exact.circles, - result.ocs.data.exact.rooms - ) - - var exactUsers = result.ocs.data.exact.users - var exactGroups = result.ocs.data.exact.groups - var exactRemotes = result.ocs.data.exact.remotes || [] - var exactRemoteGroups = result.ocs.data.exact.remote_groups || [] - var exactEmails = [] - if (typeof (result.ocs.data.emails) !== 'undefined') { - exactEmails = result.ocs.data.exact.emails - } - var exactCircles = [] - if (typeof (result.ocs.data.circles) !== 'undefined') { - exactCircles = result.ocs.data.exact.circles - } - var exactRooms = [] - if (typeof (result.ocs.data.rooms) !== 'undefined') { - exactRooms = result.ocs.data.exact.rooms - } - - var exactMatches = exactUsers.concat(exactGroups).concat(exactRemotes).concat(exactRemoteGroups).concat(exactEmails).concat(exactCircles).concat(exactRooms) - - filter( - result.ocs.data.users, - result.ocs.data.groups, - result.ocs.data.remotes, - result.ocs.data.remote_groups, - result.ocs.data.emails, - result.ocs.data.circles, - result.ocs.data.rooms - ) - - var users = result.ocs.data.users - var groups = result.ocs.data.groups - var remotes = result.ocs.data.remotes || [] - var remoteGroups = result.ocs.data.remote_groups || [] - var lookup = result.ocs.data.lookup || [] - var emails = [] - if (typeof (result.ocs.data.emails) !== 'undefined') { - emails = result.ocs.data.emails - } - var circles = [] - if (typeof (result.ocs.data.circles) !== 'undefined') { - circles = result.ocs.data.circles - } - var rooms = [] - if (typeof (result.ocs.data.rooms) !== 'undefined') { - rooms = result.ocs.data.rooms - } - - var suggestions = exactMatches.concat(users).concat(groups).concat(remotes).concat(remoteGroups).concat(emails).concat(circles).concat(rooms).concat(lookup) - - function dynamicSort(property) { - return function(a, b) { - var aProperty = '' - var bProperty = '' - if (typeof a[property] !== 'undefined') { - aProperty = a[property] - } - if (typeof b[property] !== 'undefined') { - bProperty = b[property] - } - return (aProperty < bProperty) ? -1 : (aProperty > bProperty) ? 1 : 0 - } - } - - /** - * Sort share entries by uuid to properly group them - */ - var grouped = suggestions.sort(dynamicSort('uuid')) - - var previousUuid = null - var groupedLength = grouped.length - var result = [] - /** - * build the result array that only contains all contact entries from - * merged contacts, if the search term matches its contact name - */ - for (var i = 0; i < groupedLength; i++) { - if (typeof grouped[i].uuid !== 'undefined' && grouped[i].uuid === previousUuid) { - grouped[i].merged = true - } - if (typeof grouped[i].merged === 'undefined') { - result.push(grouped[i]) - } - previousUuid = grouped[i].uuid - } - - deferred.resolve(result, exactMatches, false) - } else { - deferred.reject(result.ocs.meta.message) - } - } - ).fail(function() { - deferred.reject() - }) - - this._lastRecommendations = { - model: model, - promise: deferred.promise() - } - - return this._lastRecommendations.promise - }, - - recommendationHandler: function(response) { - var view = this - var $shareWithField = $('.shareWithField') - this._getRecommendations( - view.model - ).done(function(suggestions) { - console.info('recommendations', suggestions) - if (suggestions.length > 0) { - $shareWithField - .autocomplete('option', 'autoFocus', true) - - response(suggestions) - } else { - console.info('no sharing recommendations found') - response() - } - }).fail(function(message) { - console.error('could not load recommendations', message) - }) - }, - - autocompleteHandler: function(search, response) { - // If nothing is entered we show recommendations instead of search - // results - if (search.term.length === 0) { - console.info(search.term, 'empty search term -> using recommendations') - this.recommendationHandler(response) - return - } - - var $shareWithField = $('.shareWithField') - var view = this - var $loading = this.$el.find('.shareWithLoading') - var $confirm = this.$el.find('.shareWithConfirm') - - var count = OC.config['sharing.minSearchStringLength'] - if (search.term.trim().length < count) { - var title = n('core', - 'At least {count} character is needed for autocompletion', - 'At least {count} characters are needed for autocompletion', - count, - { count: count } - ) - $shareWithField.addClass('error') - .attr('data-original-title', title) - .tooltip('hide') - .tooltip({ - placement: 'bottom', - trigger: 'manual' - }) - .tooltip('fixTitle') - .tooltip('show') - response() - return - } - - $loading.removeClass('hidden') - $loading.addClass('inlineblock') - $confirm.addClass('hidden') - this._pendingOperationsCount++ - - $shareWithField.removeClass('error') - .tooltip('hide') - - var perPage = parseInt(OC.config['sharing.maxAutocompleteResults'], 10) || 200 - this._getSuggestions( - search.term.trim(), - perPage, - view.model, - view._lookup - ).done(function(suggestions, exactMatches, moreResultsAvailable) { - view._pendingOperationsCount-- - if (view._pendingOperationsCount === 0) { - $loading.addClass('hidden') - $loading.removeClass('inlineblock') - $confirm.removeClass('hidden') - } - - if (suggestions.length > 0) { - $shareWithField - .autocomplete('option', 'autoFocus', true) - - response(suggestions) - - // show a notice that the list is truncated - // this is the case if one of the search results is at least as long as the max result config option - if (moreResultsAvailable) { - var message = t('core', 'This list is maybe truncated - please refine your search term to see more results.') - $('.ui-autocomplete').append('<li class="autocomplete-note">' + message + '</li>') - } - - } else { - var title = t('core', 'No users or groups found for {search}', { search: $shareWithField.val() }) - if (!view.configModel.get('allowGroupSharing')) { - title = t('core', 'No users found for {search}', { search: $('.shareWithField').val() }) - } - $shareWithField.addClass('error') - .attr('data-original-title', title) - .tooltip('hide') - .tooltip({ - placement: 'top', - trigger: 'manual' - }) - .tooltip('fixTitle') - .tooltip('show') - response() - } - }).fail(function(message) { - view._pendingOperationsCount-- - if (view._pendingOperationsCount === 0) { - $loading.addClass('hidden') - $loading.removeClass('inlineblock') - $confirm.removeClass('hidden') - } - - if (message) { - OC.Notification.showTemporary(t('core', 'An error occurred ("{message}"). Please try again', { message: message })) - } else { - OC.Notification.showTemporary(t('core', 'An error occurred. Please try again')) - } - }) - }, - - autocompleteRenderItem: function(ul, item) { - var icon = 'icon-user' - var text = escapeHTML(item.label) - var description = '' - var type = '' - var getTranslatedType = function(type) { - switch (type) { - case 'HOME': - return t('core', 'Home') - case 'WORK': - return t('core', 'Work') - case 'OTHER': - return t('core', 'Other') - default: - return '' + type - } - } - if (typeof item.type !== 'undefined' && item.type !== null) { - type = getTranslatedType(item.type) + ' ' - } - - if (typeof item.name !== 'undefined') { - text = escapeHTML(item.name) - } - if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) { - icon = 'icon-contacts-dark' - } else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) { - icon = 'icon-shared' - description += item.value.shareWith - } else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP) { - text = t('core', '{sharee} (remote group)', { sharee: text }, undefined, { escape: false }) - icon = 'icon-shared' - description += item.value.shareWith - } else if (item.value.shareType === OC.Share.SHARE_TYPE_EMAIL) { - icon = 'icon-mail' - description += item.value.shareWith - } else if (item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) { - text = t('core', '{sharee} ({type}, {owner})', { sharee: text, type: item.value.circleInfo, owner: item.value.circleOwner }, undefined, { escape: false }) - icon = 'icon-circle' - } else if (item.value.shareType === OC.Share.SHARE_TYPE_ROOM) { - icon = 'icon-talk' - } - - var insert = $("<div class='share-autocomplete-item'/>") - if (item.merged) { - insert.addClass('merged') - text = item.value.shareWith - description = type - } else if (item.lookup) { - text = item.label - icon = false - insert.append('<span class="icon icon-search search-globally"></span>') - } else { - var avatar = $("<div class='avatardiv'></div>").appendTo(insert) - if (item.value.shareType === OC.Share.SHARE_TYPE_USER || item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) { - avatar.avatar(item.value.shareWith, 32, undefined, undefined, undefined, item.label) - } else { - if (typeof item.uuid === 'undefined') { - item.uuid = text - } - avatar.imageplaceholder(item.uuid, text, 32) - } - description = type + description - } - if (description !== '') { - insert.addClass('with-description') - } - - $("<div class='autocomplete-item-text'></div>") - .html( - text.replace( - new RegExp(this.term, 'gi'), - "<span class='ui-state-highlight'>$&</span>") - + '<span class="autocomplete-item-details">' + description + '</span>' - ) - .appendTo(insert) - insert.attr('title', item.value.shareWith) - if (icon) { - insert.append('<span class="icon ' + icon + '" title="' + text + '"></span>') - } - insert = $('<a>') - .append(insert) - return $('<li>') - .addClass((item.value.shareType === OC.Share.SHARE_TYPE_GROUP) ? 'group' : 'user') - .append(insert) - .appendTo(ul) - }, - - _onSelectRecipient: function(e, s) { - var self = this - - if (e.keyCode == 9) { - e.preventDefault() - if (typeof s.item.name !== 'undefined') { - e.target.value = s.item.name - } else { - e.target.value = s.item.label - } - setTimeout(function() { - $(e.target).attr('disabled', false) - .autocomplete('search', $(e.target).val()) - }, 0) - return false - } - - if (s.item.lookup) { - // Retrigger search but with global lookup this time - this._lookup = true - var $shareWithField = this.$el.find('.shareWithField') - var val = $shareWithField.val() - setTimeout(function() { - console.debug('searching again, but globally. search term: ' + val) - $shareWithField.autocomplete('search', val) - }, 0) - return false - } - - e.preventDefault() - // Ensure that the keydown handler for the input field is not - // called; otherwise it would try to add the recipient again, which - // would fail. - e.stopImmediatePropagation() - $(e.target).attr('disabled', true) - .val(s.item.label) - - var $loading = this.$el.find('.shareWithLoading') - var $confirm = this.$el.find('.shareWithConfirm') - - $loading.removeClass('hidden') - $loading.addClass('inlineblock') - $confirm.addClass('hidden') - this._pendingOperationsCount++ - - this.model.addShare(s.item.value, { success: function() { - // Adding a share changes the suggestions. - self._lastSuggestions = undefined - - $(e.target).val('') - .attr('disabled', false) - - self._pendingOperationsCount-- - if (self._pendingOperationsCount === 0) { - $loading.addClass('hidden') - $loading.removeClass('inlineblock') - $confirm.removeClass('hidden') - } - }, - error: function(obj, msg) { - OC.Notification.showTemporary(msg) - $(e.target).attr('disabled', false) - .autocomplete('search', $(e.target).val()) - - self._pendingOperationsCount-- - if (self._pendingOperationsCount === 0) { - $loading.addClass('hidden') - $loading.removeClass('inlineblock') - $confirm.removeClass('hidden') - } - } }) - }, - - _confirmShare: function() { - var self = this - var $shareWithField = $('.shareWithField') - var $loading = this.$el.find('.shareWithLoading') - var $confirm = this.$el.find('.shareWithConfirm') - - $loading.removeClass('hidden') - $loading.addClass('inlineblock') - $confirm.addClass('hidden') - this._pendingOperationsCount++ - - $shareWithField.prop('disabled', true) - - // Disabling the autocompletion does not clear its search timeout; - // removing the focus from the input field does, but only if the - // autocompletion is not disabled when the field loses the focus. - // Thus, the field has to be disabled before disabling the - // autocompletion to prevent an old pending search result from - // appearing once the field is enabled again. - $shareWithField.autocomplete('close') - $shareWithField.autocomplete('disable') - - var restoreUI = function() { - self._pendingOperationsCount-- - if (self._pendingOperationsCount === 0) { - $loading.addClass('hidden') - $loading.removeClass('inlineblock') - $confirm.removeClass('hidden') - } - - $shareWithField.prop('disabled', false) - $shareWithField.focus() - } - - var perPage = parseInt(OC.config['sharing.maxAutocompleteResults'], 10) || 200 - this._getSuggestions( - $shareWithField.val(), - perPage, - this.model, - this._lookup - ).done(function(suggestions, exactMatches) { - if (suggestions.length === 0) { - restoreUI() - - $shareWithField.autocomplete('enable') - - // There is no need to show an error message here; it will - // be automatically shown when the autocomplete is activated - // again (due to the focus on the field) and it finds no - // matches. - - return - } - - if (exactMatches.length !== 1) { - restoreUI() - - $shareWithField.autocomplete('enable') - - return - } - - var actionSuccess = function() { - // Adding a share changes the suggestions. - self._lastSuggestions = undefined - - $shareWithField.val('') - - restoreUI() - - $shareWithField.autocomplete('enable') - } - - var actionError = function(obj, msg) { - restoreUI() - - $shareWithField.autocomplete('enable') - - OC.Notification.showTemporary(msg) - } - - self.model.addShare(exactMatches[0].value, { - success: actionSuccess, - error: actionError - }) - }).fail(function(message) { - restoreUI() - - $shareWithField.autocomplete('enable') - - // There is no need to show an error message here; it will be - // automatically shown when the autocomplete is activated again - // (due to the focus on the field) and getting the suggestions - // fail. - }) - }, - - _toggleLoading: function(state) { - this._loading = state - this.$el.find('.subView').toggleClass('hidden', state) - this.$el.find('.loading').toggleClass('hidden', !state) - }, - - _onRequest: function() { - // only show the loading spinner for the first request (for now) - if (!this._loadingOnce) { - this._toggleLoading(true) - } - }, - - _onEndRequest: function() { - var self = this - this._toggleLoading(false) - if (!this._loadingOnce) { - this._loadingOnce = true - } - }, - - render: function() { - var self = this - var baseTemplate = OC.Share.Templates['sharedialogview'] - - this.$el.html(baseTemplate({ - cid: this.cid, - shareLabel: t('core', 'Share'), - sharePlaceholder: this._renderSharePlaceholderPart(), - isSharingAllowed: this.model.sharePermissionPossible() - })) - - var $shareField = this.$el.find('.shareWithField') - if ($shareField.length) { - var shareFieldKeydownHandler = function(event) { - if (event.keyCode !== 13) { - return true - } - - self._confirmShare() - - return false - } - - $shareField.autocomplete({ - minLength: 0, - delay: 750, - focus: function(event) { - event.preventDefault() - }, - source: this.autocompleteHandler, - select: this._onSelectRecipient, - open: function() { - var autocomplete = $(this).autocomplete('widget') - var numberOfItems = autocomplete.find('li').size() - autocomplete.removeClass('item-count-1') - autocomplete.removeClass('item-count-2') - if (numberOfItems <= 2) { - autocomplete.addClass('item-count-' + numberOfItems) - } - } - }).data('ui-autocomplete')._renderItem = this.autocompleteRenderItem - - $shareField.on('keydown', null, shareFieldKeydownHandler) - } - - this.resharerInfoView.$el = this.$el.find('.resharerInfoView') - this.resharerInfoView.render() - - this.linkShareView.$el = this.$el.find('.linkShareView') - this.linkShareView.render() - - this.shareeListView.$el = this.$el.find('.shareeListView') - this.shareeListView.render() - - this.$el.find('.hasTooltip').tooltip() - - return this - }, - - /** - * sets whether share by link should be displayed or not. Default is - * true. - * - * @param {bool} showLink - */ - setShowLink: function(showLink) { - this._showLink = (typeof showLink === 'boolean') ? showLink : true - this.linkShareView.showLink = this._showLink - }, - - _renderSharePlaceholderPart: function() { - var allowRemoteSharing = this.configModel.get('isRemoteShareAllowed') - var allowMailSharing = this.configModel.get('isMailShareAllowed') - - if (!allowRemoteSharing && allowMailSharing) { - return t('core', 'Name or email address...') - } - if (allowRemoteSharing && !allowMailSharing) { - return t('core', 'Name or federated cloud ID...') - } - if (allowRemoteSharing && allowMailSharing) { - return t('core', 'Name, federated cloud ID or email address...') - } - - return t('core', 'Name...') - } - - }) - - OC.Share.ShareDialogView = ShareDialogView - -})() diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js deleted file mode 100644 index e86731ab1b1514012f36b9c285ee69d79cf273cd..0000000000000000000000000000000000000000 --- a/core/js/shareitemmodel.js +++ /dev/null @@ -1,945 +0,0 @@ -/* eslint-disable */ -/* - * Copyright (c) 2015 - * - * This file is licensed under the Affero General Public License version 3 - * or later. - * - * See the COPYING-README file. - * - */ - -(function() { - if (!OC.Share) { - OC.Share = {} - OC.Share.Types = {} - } - - /** - * @typedef {object} OC.Share.Types.LinkShareInfo - * @property {string} token - * @property {bool} hideDownload - * @property {string|null} password - * @property {bool} sendPasswordByTalk - * @property {number} permissions - * @property {Date} expiration - * @property {number} stime share time - */ - - /** - * @typedef {object} OC.Share.Types.Reshare - * @property {string} uid_owner - * @property {number} share_type - * @property {string} share_with - * @property {string} displayname_owner - * @property {number} permissions - */ - - /** - * @typedef {object} OC.Share.Types.ShareInfo - * @property {number} share_type - * @property {number} permissions - * @property {number} file_source optional - * @property {number} item_source - * @property {string} token - * @property {string} share_with - * @property {string} share_with_displayname - * @property {string} share_with_avatar - * @property {string} mail_send - * @property {Date} expiration optional? - * @property {number} stime optional? - * @property {string} uid_owner - * @property {string} displayname_owner - */ - - /** - * @typedef {object} OC.Share.Types.ShareItemInfo - * @property {OC.Share.Types.Reshare} reshare - * @property {OC.Share.Types.ShareInfo[]} shares - * @property {OC.Share.Types.LinkShareInfo|undefined} linkShare - */ - - /** - * These properties are sometimes returned by the server as strings instead - * of integers, so we need to convert them accordingly... - */ - var SHARE_RESPONSE_INT_PROPS = [ - 'id', 'file_parent', 'mail_send', 'file_source', 'item_source', 'permissions', - 'storage', 'share_type', 'parent', 'stime' - ] - - /** - * @class OCA.Share.ShareItemModel - * @classdesc - * - * Represents the GUI of the share dialogue - * - * // FIXME: use OC Share API once #17143 is done - * - * // TODO: this really should be a collection of share item models instead, - * where the link share is one of them - */ - var ShareItemModel = OC.Backbone.Model.extend({ - /** - * share id of the link share, if applicable - */ - _linkShareId: null, - - initialize: function(attributes, options) { - if (!_.isUndefined(options.configModel)) { - this.configModel = options.configModel - } - if (!_.isUndefined(options.fileInfoModel)) { - /** @type {OC.Files.FileInfo} **/ - this.fileInfoModel = options.fileInfoModel - } - - _.bindAll(this, 'addShare') - }, - - defaults: { - allowPublicUploadStatus: false, - permissions: 0, - linkShares: [] - }, - - /** - * Saves the current link share information. - * - * This will trigger an ajax call and, if successful, refetch the model - * afterwards. Callbacks "success", "error" and "complete" can be given - * in the options object; "success" is called after a successful save - * once the model is refetch, "error" is called after a failed save, and - * "complete" is called both after a successful save and after a failed - * save. Note that "complete" is called before "success" and "error" are - * called (unlike in jQuery, in which it is called after them); this - * ensures that "complete" is called even if refetching the model fails. - * - * TODO: this should be a separate model - */ - saveLinkShare: function(attributes, options) { - options = options || {} - attributes = _.extend({}, attributes) - - var shareId = null - var call - - // oh yeah... - if (attributes.expiration) { - attributes.expireDate = attributes.expiration - delete attributes.expiration - } - - var linkShares = this.get('linkShares') - var shareIndex = _.findIndex(linkShares, function(share) { return share.id === attributes.cid }) - - if (linkShares.length > 0 && shareIndex !== -1) { - shareId = linkShares[shareIndex].id - - // note: update can only update a single value at a time - call = this.updateShare(shareId, attributes, options) - } else { - attributes = _.defaults(attributes, { - hideDownload: false, - password: '', - passwordChanged: false, - sendPasswordByTalk: false, - permissions: OC.PERMISSION_READ, - expireDate: this.configModel.getDefaultExpirationDateString(), - shareType: OC.Share.SHARE_TYPE_LINK - }) - - call = this.addShare(attributes, options) - } - - return call - }, - - addShare: function(attributes, options) { - var shareType = attributes.shareType - attributes = _.extend({}, attributes) - - // get default permissions - var defaultPermissions = OC.getCapabilities()['files_sharing']['default_permissions'] || OC.PERMISSION_ALL - var possiblePermissions = OC.PERMISSION_READ - - if (this.updatePermissionPossible()) { - possiblePermissions = possiblePermissions | OC.PERMISSION_UPDATE - } - if (this.createPermissionPossible()) { - possiblePermissions = possiblePermissions | OC.PERMISSION_CREATE - } - if (this.deletePermissionPossible()) { - possiblePermissions = possiblePermissions | OC.PERMISSION_DELETE - } - if (this.configModel.get('isResharingAllowed') && (this.sharePermissionPossible())) { - possiblePermissions = possiblePermissions | OC.PERMISSION_SHARE - } - - attributes.permissions = defaultPermissions & possiblePermissions - if (_.isUndefined(attributes.path)) { - attributes.path = this.fileInfoModel.getFullPath() - } - - return this._addOrUpdateShare({ - type: 'POST', - url: this._getUrl('shares'), - data: attributes, - dataType: 'json' - }, options) - }, - - updateShare: function(shareId, attrs, options) { - return this._addOrUpdateShare({ - type: 'PUT', - url: this._getUrl('shares/' + encodeURIComponent(shareId)), - data: attrs, - dataType: 'json' - }, options) - }, - - _addOrUpdateShare: function(ajaxSettings, options) { - var self = this - options = options || {} - - return $.ajax( - ajaxSettings - ).always(function() { - if (_.isFunction(options.complete)) { - options.complete(self) - } - }).done(function() { - self.fetch().done(function() { - if (_.isFunction(options.success)) { - options.success(self) - } - }) - }).fail(function(xhr) { - var msg = t('core', 'Error') - var result = xhr.responseJSON - if (result && result.ocs && result.ocs.meta) { - msg = result.ocs.meta.message - } - - if (_.isFunction(options.error)) { - options.error(self, msg) - } else { - OC.dialogs.alert(msg, t('core', 'Error while sharing')) - } - }) - }, - - /** - * Deletes the share with the given id - * - * @param {int} shareId share id - * @returns {jQuery} - */ - removeShare: function(shareId, options) { - var self = this - options = options || {} - return $.ajax({ - type: 'DELETE', - url: this._getUrl('shares/' + encodeURIComponent(shareId)) - }).done(function() { - self.fetch({ - success: function() { - if (_.isFunction(options.success)) { - options.success(self) - } - } - }) - }).fail(function(xhr) { - var msg = t('core', 'Error') - var result = xhr.responseJSON - if (result.ocs && result.ocs.meta) { - msg = result.ocs.meta.message - } - - if (_.isFunction(options.error)) { - options.error(self, msg) - } else { - OC.dialogs.alert(msg, t('core', 'Error removing share')) - } - }) - }, - - /** - * @returns {boolean} - */ - isPublicUploadAllowed: function() { - return this.get('allowPublicUploadStatus') - }, - - isPublicEditingAllowed: function() { - return this.get('allowPublicEditingStatus') - }, - - /** - * @returns {boolean} - */ - isHideFileListSet: function() { - return this.get('hideFileListStatus') - }, - - /** - * @returns {boolean} - */ - isFolder: function() { - return this.get('itemType') === 'folder' - }, - - /** - * @returns {boolean} - */ - isFile: function() { - return this.get('itemType') === 'file' - }, - - /** - * whether this item has reshare information - * @returns {boolean} - */ - hasReshare: function() { - var reshare = this.get('reshare') - return _.isObject(reshare) && !_.isUndefined(reshare.uid_owner) - }, - - /** - * whether this item has user share information - * @returns {boolean} - */ - hasUserShares: function() { - return this.getSharesWithCurrentItem().length > 0 - }, - - /** - * Returns whether this item has link shares - * - * @returns {bool} true if a link share exists, false otherwise - */ - hasLinkShares: function() { - var linkShares = this.get('linkShares') - if (linkShares && linkShares.length > 0) { - return true - } - return false - }, - - /** - * @returns {string} - */ - getReshareOwner: function() { - return this.get('reshare').uid_owner - }, - - /** - * @returns {string} - */ - getReshareOwnerDisplayname: function() { - return this.get('reshare').displayname_owner - }, - - /** - * @returns {string} - */ - getReshareNote: function() { - return this.get('reshare').note - }, - - /** - * @returns {string} - */ - getReshareWith: function() { - return this.get('reshare').share_with - }, - - /** - * @returns {string} - */ - getReshareWithDisplayName: function() { - var reshare = this.get('reshare') - return reshare.share_with_displayname || reshare.share_with - }, - - /** - * @returns {number} - */ - getReshareType: function() { - return this.get('reshare').share_type - }, - - getExpireDate: function(shareIndex) { - return this._shareExpireDate(shareIndex) - }, - - getNote: function(shareIndex) { - return this._shareNote(shareIndex) - }, - - /** - * Returns all share entries that only apply to the current item - * (file/folder) - * - * @returns {Array.<OC.Share.Types.ShareInfo>} - */ - getSharesWithCurrentItem: function() { - var shares = this.get('shares') || [] - var fileId = this.fileInfoModel.get('id') - return _.filter(shares, function(share) { - return share.item_source === fileId - }) - }, - - /** - * @param shareIndex - * @returns {string} - */ - getShareWith: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.share_with - }, - - /** - * @param shareIndex - * @returns {string} - */ - getShareWithDisplayName: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.share_with_displayname - }, - - /** - * @param shareIndex - * @returns {string} - */ - getShareWithAvatar: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.share_with_avatar - }, - - /** - * @param shareIndex - * @returns {string} - */ - getSharedBy: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.uid_owner - }, - - /** - * @param shareIndex - * @returns {string} - */ - getSharedByDisplayName: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.displayname_owner - }, - - /** - * @param shareIndex - * @returns {string} - */ - getFileOwnerUid: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.uid_file_owner - }, - - /** - * returns the array index of a sharee for a provided shareId - * - * @param shareId - * @returns {number} - */ - findShareWithIndex: function(shareId) { - var shares = this.get('shares') - if (!_.isArray(shares)) { - throw 'Unknown Share' - } - for (var i = 0; i < shares.length; i++) { - var shareWith = shares[i] - if (shareWith.id === shareId) { - return i - } - } - throw 'Unknown Sharee' - }, - - getShareType: function(shareIndex) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.share_type - }, - - /** - * whether a share from shares has the requested permission - * - * @param {number} shareIndex - * @param {number} permission - * @returns {boolean} - * @private - */ - _shareHasPermission: function(shareIndex, permission) { - /** @type OC.Share.Types.ShareInfo **/ - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return (share.permissions & permission) === permission - }, - - _shareExpireDate: function(shareIndex) { - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - var date2 = share.expiration - return date2 - }, - - _shareNote: function(shareIndex) { - var share = this.get('shares')[shareIndex] - if (!_.isObject(share)) { - throw 'Unknown Share' - } - return share.note - }, - - /** - * @returns {int} - */ - getPermissions: function() { - return this.get('permissions') - }, - - /** - * @returns {boolean} - */ - sharePermissionPossible: function() { - return (this.get('permissions') & OC.PERMISSION_SHARE) === OC.PERMISSION_SHARE - }, - - /** - * @param {number} shareIndex - * @returns {boolean} - */ - hasSharePermission: function(shareIndex) { - return this._shareHasPermission(shareIndex, OC.PERMISSION_SHARE) - }, - - /** - * @returns {boolean} - */ - createPermissionPossible: function() { - return (this.get('permissions') & OC.PERMISSION_CREATE) === OC.PERMISSION_CREATE - }, - - /** - * @param {number} shareIndex - * @returns {boolean} - */ - hasCreatePermission: function(shareIndex) { - return this._shareHasPermission(shareIndex, OC.PERMISSION_CREATE) - }, - - /** - * @returns {boolean} - */ - updatePermissionPossible: function() { - return (this.get('permissions') & OC.PERMISSION_UPDATE) === OC.PERMISSION_UPDATE - }, - - /** - * @param {number} shareIndex - * @returns {boolean} - */ - hasUpdatePermission: function(shareIndex) { - return this._shareHasPermission(shareIndex, OC.PERMISSION_UPDATE) - }, - - /** - * @returns {boolean} - */ - deletePermissionPossible: function() { - return (this.get('permissions') & OC.PERMISSION_DELETE) === OC.PERMISSION_DELETE - }, - - /** - * @param {number} shareIndex - * @returns {boolean} - */ - hasDeletePermission: function(shareIndex) { - return this._shareHasPermission(shareIndex, OC.PERMISSION_DELETE) - }, - - hasReadPermission: function(shareIndex) { - return this._shareHasPermission(shareIndex, OC.PERMISSION_READ) - }, - - /** - * @returns {boolean} - */ - editPermissionPossible: function() { - return this.createPermissionPossible() - || this.updatePermissionPossible() - || this.deletePermissionPossible() - }, - - /** - * @returns {string} - * The state that the 'can edit' permission checkbox should have. - * Possible values: - * - empty string: no permission - * - 'checked': all applicable permissions - * - 'indeterminate': some but not all permissions - */ - editPermissionState: function(shareIndex) { - var hcp = this.hasCreatePermission(shareIndex) - var hup = this.hasUpdatePermission(shareIndex) - var hdp = this.hasDeletePermission(shareIndex) - if (this.isFile()) { - if (hcp || hup || hdp) { - return 'checked' - } - return '' - } - if (!hcp && !hup && !hdp) { - return '' - } - if ((this.createPermissionPossible() && !hcp) - || (this.updatePermissionPossible() && !hup) - || (this.deletePermissionPossible() && !hdp)) { - return 'indeterminate' - } - return 'checked' - }, - - /** - * @returns {int} - */ - linkSharePermissions: function(shareId) { - var linkShares = this.get('linkShares') - var shareIndex = _.findIndex(linkShares, function(share) { return share.id === shareId }) - - if (!this.hasLinkShares()) { - return -1 - } else if (linkShares.length > 0 && shareIndex !== -1) { - return linkShares[shareIndex].permissions - } - return -1 - }, - - _getUrl: function(base, params) { - params = _.extend({ format: 'json' }, params || {}) - return OC.linkToOCS('apps/files_sharing/api/v1', 2) + base + '?' + OC.buildQueryString(params) - }, - - _fetchShares: function() { - var path = this.fileInfoModel.getFullPath() - return $.ajax({ - type: 'GET', - url: this._getUrl('shares', { path: path, reshares: true }) - }) - }, - - _fetchReshare: function() { - // only fetch original share once - if (!this._reshareFetched) { - var path = this.fileInfoModel.getFullPath() - this._reshareFetched = true - return $.ajax({ - type: 'GET', - url: this._getUrl('shares', { path: path, shared_with_me: true }) - }) - } else { - return $.Deferred().resolve([{ - ocs: { - data: [this.get('reshare')] - } - }]) - } - }, - - /** - * Group reshares into a single super share element. - * Does this by finding the most precise share and - * combines the permissions to be the most permissive. - * - * @param {Array} reshares - * @returns {Object} reshare - */ - _groupReshares: function(reshares) { - if (!reshares || !reshares.length) { - return false - } - - var superShare = reshares.shift() - var combinedPermissions = superShare.permissions - _.each(reshares, function(reshare) { - // use share have higher priority than group share - if (reshare.share_type === OC.Share.SHARE_TYPE_USER && superShare.share_type === OC.Share.SHARE_TYPE_GROUP) { - superShare = reshare - } - combinedPermissions |= reshare.permissions - }) - - superShare.permissions = combinedPermissions - return superShare - }, - - fetch: function(options) { - var model = this - this.trigger('request', this) - - var deferred = $.when( - this._fetchShares(), - this._fetchReshare() - ) - deferred.done(function(data1, data2) { - model.trigger('sync', 'GET', this) - var sharesMap = {} - _.each(data1[0].ocs.data, function(shareItem) { - sharesMap[shareItem.id] = shareItem - }) - - var reshare = false - if (data2[0].ocs.data.length) { - reshare = model._groupReshares(data2[0].ocs.data) - } - - model.set(model.parse({ - shares: sharesMap, - reshare: reshare - })) - - if (!_.isUndefined(options) && _.isFunction(options.success)) { - options.success() - } - }) - - return deferred - }, - - /** - * Updates OC.Share.itemShares and OC.Share.statuses. - * - * This is required in case the user navigates away and comes back, - * the share statuses from the old arrays are still used to fill in the icons - * in the file list. - */ - _legacyFillCurrentShares: function(shares) { - var fileId = this.fileInfoModel.get('id') - if (!shares || !shares.length) { - delete OC.Share.statuses[fileId] - OC.Share.currentShares = {} - OC.Share.itemShares = [] - return - } - - var currentShareStatus = OC.Share.statuses[fileId] - if (!currentShareStatus) { - currentShareStatus = { link: false } - OC.Share.statuses[fileId] = currentShareStatus - } - currentShareStatus.link = false - - OC.Share.currentShares = {} - OC.Share.itemShares = [] - _.each(shares, - /** - * @param {OC.Share.Types.ShareInfo} share - */ - function(share) { - if (share.share_type === OC.Share.SHARE_TYPE_LINK) { - OC.Share.itemShares[share.share_type] = true - currentShareStatus.link = true - } else { - if (!OC.Share.itemShares[share.share_type]) { - OC.Share.itemShares[share.share_type] = [] - } - OC.Share.itemShares[share.share_type].push(share.share_with) - } - } - ) - }, - - parse: function(data) { - if (data === false) { - console.warn('no data was returned') - this.trigger('fetchError') - return {} - } - - var permissions = this.fileInfoModel.get('permissions') - if (!_.isUndefined(data.reshare) && !_.isUndefined(data.reshare.permissions) && data.reshare.uid_owner !== OC.currentUser) { - permissions = permissions & data.reshare.permissions - } - - var allowPublicUploadStatus = false - if (!_.isUndefined(data.shares)) { - $.each(data.shares, function(key, value) { - if (value.share_type === OC.Share.SHARE_TYPE_LINK) { - allowPublicUploadStatus = !!((value.permissions & OC.PERMISSION_CREATE)) - return true - } - }) - } - - var allowPublicEditingStatus = true - if (!_.isUndefined(data.shares)) { - $.each(data.shares, function(key, value) { - if (value.share_type === OC.Share.SHARE_TYPE_LINK) { - allowPublicEditingStatus = !!((value.permissions & OC.PERMISSION_UPDATE)) - return true - } - }) - } - - var hideFileListStatus = false - if (!_.isUndefined(data.shares)) { - $.each(data.shares, function(key, value) { - if (value.share_type === OC.Share.SHARE_TYPE_LINK) { - hideFileListStatus = !((value.permissions & OC.PERMISSION_READ)) - return true - } - }) - } - - /** @type {OC.Share.Types.ShareInfo[]} **/ - var shares = _.map(data.shares, function(share) { - // properly parse some values because sometimes the server - // returns integers as string... - var i - for (i = 0; i < SHARE_RESPONSE_INT_PROPS.length; i++) { - var prop = SHARE_RESPONSE_INT_PROPS[i] - if (!_.isUndefined(share[prop])) { - share[prop] = parseInt(share[prop], 10) - } - } - return share - }) - - this._legacyFillCurrentShares(shares) - - var linkShares = [] - // filter out the share by link - shares = _.reject(shares, - /** - * @param {OC.Share.Types.ShareInfo} share - */ - function(share) { - var isShareLink - = share.share_type === OC.Share.SHARE_TYPE_LINK - && (share.file_source === this.get('itemSource') - || share.item_source === this.get('itemSource')) - - if (isShareLink) { - /** - * Ignore reshared link shares for now - * FIXME: Find a way to display properly - */ - if (share.uid_owner !== OC.currentUser) { - return - } - - var link = window.location.protocol + '//' + window.location.host - if (!share.token) { - // pre-token link - var fullPath = this.fileInfoModel.get('path') + '/' - + this.fileInfoModel.get('name') - var location = '/' + OC.currentUser + '/files' + fullPath - var type = this.fileInfoModel.isDirectory() ? 'folder' : 'file' - link += OC.linkTo('', 'public.php') + '?service=files&' - + type + '=' + encodeURIComponent(location) - } else { - link += OC.generateUrl('/s/') + share.token - } - linkShares.push(_.extend({}, share, { - // hide_download is returned as an int, so force it - // to a boolean - hideDownload: !!share.hide_download, - password: share.share_with, - sendPasswordByTalk: share.send_password_by_talk - })) - - return share - } - }, - this - ) - - return { - reshare: data.reshare, - shares: shares, - linkShares: linkShares, - permissions: permissions, - allowPublicUploadStatus: allowPublicUploadStatus, - allowPublicEditingStatus: allowPublicEditingStatus, - hideFileListStatus: hideFileListStatus - } - }, - - /** - * Parses a string to an valid integer (unix timestamp) - * @param time - * @returns {*} - * @internal Only used to work around a bug in the backend - */ - _parseTime: function(time) { - if (_.isString(time)) { - // skip empty strings and hex values - if (time === '' || (time.length > 1 && time[0] === '0' && time[1] === 'x')) { - return null - } - time = parseInt(time, 10) - if (isNaN(time)) { - time = null - } - } - return time - }, - - /** - * Returns a list of share types from the existing shares. - * - * @returns {Array.<int>} array of share types - */ - getShareTypes: function() { - var result - result = _.pluck(this.getSharesWithCurrentItem(), 'share_type') - if (this.hasLinkShares()) { - result.push(OC.Share.SHARE_TYPE_LINK) - } - return _.uniq(result) - } - }) - - OC.Share.ShareItemModel = ShareItemModel -})() diff --git a/core/js/sharesocialmanager.js b/core/js/sharesocialmanager.js deleted file mode 100644 index 65fc4cd0f65054bc2132e1b21b1e4032aa756a32..0000000000000000000000000000000000000000 --- a/core/js/sharesocialmanager.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @copyright 2017, Roeland Jago Douma <roeland@famdouma.nl> - * - * @author Roeland Jago Douma <roeland@famdouma.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -(function() { - if (!OC.Share) { - OC.Share = {} - } - - OC.Share.Social = {} - - var SocialModel = OC.Backbone.Model.extend({ - defaults: { - /** used for sorting social buttons */ - key: null, - /** url to open, {{reference}} will be replaced with the link */ - url: null, - /** Name to show in the tooltip */ - name: null, - /** Icon class to display */ - iconClass: null, - /** Open in new windows */ - newWindow: true - } - }) - - OC.Share.Social.Model = SocialModel - - var SocialCollection = OC.Backbone.Collection.extend({ - model: OC.Share.Social.Model, - - comparator: 'key' - }) - - OC.Share.Social.Collection = new SocialCollection() -})() diff --git a/core/js/sharetemplates.js b/core/js/sharetemplates.js deleted file mode 100644 index a23b51b27bc0249b45b6310c4161b738a10d8efb..0000000000000000000000000000000000000000 --- a/core/js/sharetemplates.js +++ /dev/null @@ -1,686 +0,0 @@ -(function() { - var template = Handlebars.template, templates = OC.Share.Templates = OC.Share.Templates || {}; -templates['sharedialoglinkshareview'] = template({"1":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}); - - return "<ul class=\"shareWithList\">\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.nolinkShares : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + ((stack1 = helpers.each.call(alias2,(depth0 != null ? depth0.linkShares : depth0),{"name":"each","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "</ul>\n"; -},"2":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li data-share-id=\"" - + alias5(((helper = (helper = helpers.newShareId || (depth0 != null ? depth0.newShareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"newShareId","hash":{},"data":data}) : helper))) - + "\">\n <div class=\"avatar icon-public-white\"></div>\n <span class=\"username\">" - + alias5(((helper = (helper = helpers.newShareLabel || (depth0 != null ? depth0.newShareLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"newShareLabel","hash":{},"data":data}) : helper))) - + "</span>\n <span class=\"sharingOptionsGroup\">\n <div class=\"share-menu\">\n <a href=\"#\" class=\"icon icon-add new-share has-tooltip " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\" title=\"" - + alias5(((helper = (helper = helpers.newShareTitle || (depth0 != null ? depth0.newShareTitle : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"newShareTitle","hash":{},"data":data}) : helper))) - + "\"></a>\n <span class=\"icon icon-loading-small " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.showPending : depth0),{"name":"unless","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\"></span>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " </div>\n </span>\n </li>\n"; -},"3":function(container,depth0,helpers,partials,data) { - return "hidden"; -},"5":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable; - - return " " - + ((stack1 = ((helper = (helper = helpers.pendingPopoverMenu || (depth0 != null ? depth0.pendingPopoverMenu : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"pendingPopoverMenu","hash":{},"data":data}) : helper))) != null ? stack1 : "") - + "\n"; -},"7":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li data-share-id=\"" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">\n <div class=\"avatar icon-public-white\"></div>\n <span class=\"username\" title=\"" - + alias5(((helper = (helper = helpers.linkShareCreationDate || (depth0 != null ? depth0.linkShareCreationDate : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"linkShareCreationDate","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.linkShareLabel || (depth0 != null ? depth0.linkShareLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"linkShareLabel","hash":{},"data":data}) : helper))) - + "</span>\n \n <span class=\"sharingOptionsGroup\">\n <a href=\"#\" class=\"clipboard-button icon icon-clippy has-tooltip\" data-clipboard-text=\"" - + alias5(((helper = (helper = helpers.shareLinkURL || (depth0 != null ? depth0.shareLinkURL : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareLinkURL","hash":{},"data":data}) : helper))) - + "\" title=\"" - + alias5(((helper = (helper = helpers.copyLabel || (depth0 != null ? depth0.copyLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"copyLabel","hash":{},"data":data}) : helper))) - + "\"></a>\n <div class=\"share-menu\">\n <a href=\"#\" class=\"icon icon-more " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\"></a>\n <span class=\"icon icon-loading-small " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.showPending : depth0),{"name":"unless","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\"></span>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(8, data, 0),"data":data})) != null ? stack1 : "") - + " </div>\n </span>\n </li>\n"; -},"8":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable; - - return " " - + ((stack1 = ((helper = (helper = helpers.popoverMenu || (depth0 != null ? depth0.popoverMenu : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"popoverMenu","hash":{},"data":data}) : helper))) != null ? stack1 : "") - + "\n"; -},"10":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.noSharingPlaceholder : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\n"; -},"11":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "<input id=\"shareWith-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"shareWithField\" type=\"text\" placeholder=\"" - + alias5(((helper = (helper = helpers.noSharingPlaceholder || (depth0 != null ? depth0.noSharingPlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"noSharingPlaceholder","hash":{},"data":data}) : helper))) - + "\" disabled=\"disabled\" />"; -},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.shareAllowed : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(10, data, 0),"data":data})) != null ? stack1 : ""); -},"useData":true}); -templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li>\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\"" - + alias5(((helper = (helper = helpers.publicUploadRValue || (depth0 != null ? depth0.publicUploadRValue : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadRValue","hash":{},"data":data}) : helper))) - + "\" id=\"sharingDialogAllowPublicUpload-r-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"radio publicUploadRadio\" " - + ((stack1 = ((helper = (helper = helpers.publicUploadRChecked || (depth0 != null ? depth0.publicUploadRChecked : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadRChecked","hash":{},"data":data}) : helper))) != null ? stack1 : "") - + " />\n <label for=\"sharingDialogAllowPublicUpload-r-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.publicUploadRLabel || (depth0 != null ? depth0.publicUploadRLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadRLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li>\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\"" - + alias5(((helper = (helper = helpers.publicUploadRWValue || (depth0 != null ? depth0.publicUploadRWValue : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadRWValue","hash":{},"data":data}) : helper))) - + "\" id=\"sharingDialogAllowPublicUpload-rw-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"radio publicUploadRadio\" " - + ((stack1 = ((helper = (helper = helpers.publicUploadRWChecked || (depth0 != null ? depth0.publicUploadRWChecked : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadRWChecked","hash":{},"data":data}) : helper))) != null ? stack1 : "") - + " />\n <label for=\"sharingDialogAllowPublicUpload-rw-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.publicUploadRWLabel || (depth0 != null ? depth0.publicUploadRWLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadRWLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li>\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\"" - + alias5(((helper = (helper = helpers.publicUploadWValue || (depth0 != null ? depth0.publicUploadWValue : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadWValue","hash":{},"data":data}) : helper))) - + "\" id=\"sharingDialogAllowPublicUpload-w-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"radio publicUploadRadio\" " - + ((stack1 = ((helper = (helper = helpers.publicUploadWChecked || (depth0 != null ? depth0.publicUploadWChecked : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadWChecked","hash":{},"data":data}) : helper))) != null ? stack1 : "") - + " />\n <label for=\"sharingDialogAllowPublicUpload-w-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.publicUploadWLabel || (depth0 != null ? depth0.publicUploadWLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicUploadWLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n"; -},"3":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li id=\"allowPublicEditingWrapper\">\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"allowPublicEditing\" id=\"sharingDialogAllowPublicEditing-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"checkbox publicEditingCheckbox\" " - + ((stack1 = ((helper = (helper = helpers.publicEditingChecked || (depth0 != null ? depth0.publicEditingChecked : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicEditingChecked","hash":{},"data":data}) : helper))) != null ? stack1 : "") - + " />\n <label for=\"sharingDialogAllowPublicEditing-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.publicEditingLabel || (depth0 != null ? depth0.publicEditingLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"publicEditingLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n"; -},"5":function(container,depth0,helpers,partials,data) { - return "checked=\"checked\""; -},"7":function(container,depth0,helpers,partials,data) { - return "disabled=\"disabled\""; -},"9":function(container,depth0,helpers,partials,data) { - return "hidden"; -},"11":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li>\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"passwordByTalk\" id=\"passwordByTalk-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"checkbox passwordByTalkCheckbox\"\n " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isPasswordByTalkSet : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " />\n <label for=\"passwordByTalk-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.passwordByTalkLabel || (depth0 != null ? depth0.passwordByTalkLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordByTalkLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n"; -},"13":function(container,depth0,helpers,partials,data) { - return "datepicker"; -},"15":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable; - - return container.escapeExpression(((helper = (helper = helpers.expireDate || (depth0 != null ? depth0.expireDate : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"expireDate","hash":{},"data":data}) : helper))); -},"17":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable; - - return container.escapeExpression(((helper = (helper = helpers.defaultExpireDate || (depth0 != null ? depth0.defaultExpireDate : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"defaultExpireDate","hash":{},"data":data}) : helper))); -},"19":function(container,depth0,helpers,partials,data) { - return "readonly"; -},"21":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li>\n <a href=\"#\" class=\"menuitem pop-up\" data-url=\"" - + alias5(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"url","hash":{},"data":data}) : helper))) - + "\" data-window=\"" - + alias5(((helper = (helper = helpers.newWindow || (depth0 != null ? depth0.newWindow : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"newWindow","hash":{},"data":data}) : helper))) - + "\">\n <span class=\"icon " - + alias5(((helper = (helper = helpers.iconClass || (depth0 != null ? depth0.iconClass : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"iconClass","hash":{},"data":data}) : helper))) - + "\"></span>\n <span>" - + alias5(((helper = (helper = helpers.label || (depth0 != null ? depth0.label : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"label","hash":{},"data":data}) : helper))) - + "</span>\n </a>\n </li>\n"; -},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "<div class=\"popovermenu menu\">\n <ul>\n <li class=\"hidden linkTextMenu\">\n <span class=\"menuitem icon-link-text\">\n <input id=\"linkText-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"linkText\" type=\"text\" readonly=\"readonly\" value=\"" - + alias5(((helper = (helper = helpers.shareLinkURL || (depth0 != null ? depth0.shareLinkURL : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareLinkURL","hash":{},"data":data}) : helper))) - + "\" />\n </span>\n </li>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.publicUpload : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.publicEditing : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " <li>\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"hideDownload\" id=\"sharingDialogHideDownload-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"checkbox hideDownloadCheckbox\"\n " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hideDownload : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " />\n <label for=\"sharingDialogHideDownload-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.hideDownloadLabel || (depth0 != null ? depth0.hideDownloadLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"hideDownloadLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li>\n <span class=\"menuitem\">\n <input type=\"checkbox\" name=\"showPassword\" id=\"showPassword-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"checkbox showPasswordCheckbox\"\n " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isPasswordEnforced : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " value=\"1\" />\n <label for=\"showPassword-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.enablePasswordLabel || (depth0 != null ? depth0.enablePasswordLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"enablePasswordLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li class=\"" - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"unless","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " linkPassMenu\">\n <span class=\"menuitem icon-share-pass\">\n <input id=\"linkPassText-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"linkPassText\" type=\"password\" placeholder=\"" - + alias5(((helper = (helper = helpers.passwordPlaceholder || (depth0 != null ? depth0.passwordPlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordPlaceholder","hash":{},"data":data}) : helper))) - + "\" autocomplete=\"new-password\" />\n <input type=\"submit\" class=\"icon-confirm share-pass-submit\" value=\"\" />\n <span class=\"icon icon-loading-small hidden\"></span>\n </span>\n </li>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.showPasswordByTalkCheckBox : depth0),{"name":"if","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " <li>\n <span class=\"menuitem\">\n <input id=\"expireDate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"expirationDate\" class=\"expireDate checkbox\"\n " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " />\n <label for=\"expireDate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.expireDateLabel || (depth0 != null ? depth0.expireDateLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expireDateLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li class=\"" - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"unless","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n <span class=\"menuitem icon-expiredate expirationDateContainer-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\">\n <label for=\"expirationDatePicker-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"hidden-visually\" value=\"" - + alias5(((helper = (helper = helpers.expirationDate || (depth0 != null ? depth0.expirationDate : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expirationDate","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.expirationLabel || (depth0 != null ? depth0.expirationLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expirationLabel","hash":{},"data":data}) : helper))) - + "</label>\n <!-- do not use the datepicker if enforced -->\n <input id=\"expirationDatePicker-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"" - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"unless","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\" type=\"text\"\n placeholder=\"" - + alias5(((helper = (helper = helpers.expirationDatePlaceholder || (depth0 != null ? depth0.expirationDatePlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expirationDatePlaceholder","hash":{},"data":data}) : helper))) - + "\" value=\"" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(15, data, 0),"inverse":container.program(17, data, 0),"data":data})) != null ? stack1 : "") - + "\"\n data-max-date=\"" - + alias5(((helper = (helper = helpers.maxDate || (depth0 != null ? depth0.maxDate : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"maxDate","hash":{},"data":data}) : helper))) - + "\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"if","hash":{},"fn":container.program(19, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " />\n </span>\n </li>\n <li>\n <a href=\"#\" class=\"share-add\">\n <span class=\"icon-loading-small hidden\"></span>\n <span class=\"icon icon-edit\"></span>\n <span>" - + alias5(((helper = (helper = helpers.addNoteLabel || (depth0 != null ? depth0.addNoteLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"addNoteLabel","hash":{},"data":data}) : helper))) - + "</span>\n <input type=\"button\" class=\"share-note-delete icon-delete " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.hasNote : depth0),{"name":"unless","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n </a>\n </li>\n <li class=\"share-note-form share-note-link " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.hasNote : depth0),{"name":"unless","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n <span class=\"menuitem icon-note\">\n <textarea class=\"share-note\">" - + alias5(((helper = (helper = helpers.shareNote || (depth0 != null ? depth0.shareNote : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareNote","hash":{},"data":data}) : helper))) - + "</textarea>\n <input type=\"submit\" class=\"icon-confirm share-note-submit\" value=\"\" id=\"add-note-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" />\n </span>\n </li>\n" - + ((stack1 = helpers.each.call(alias2,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(21, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " <li>\n <a href=\"#\" class=\"unshare\"><span class=\"icon-loading-small hidden\"></span><span class=\"icon icon-delete\"></span><span>" - + alias5(((helper = (helper = helpers.unshareLinkLabel || (depth0 != null ? depth0.unshareLinkLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"unshareLinkLabel","hash":{},"data":data}) : helper))) - + "</span></a>\n </li>\n <li>\n <a href=\"#\" class=\"new-share\">\n <span class=\"icon-loading-small hidden\"></span>\n <span class=\"icon icon-add\"></span>\n <span>" - + alias5(((helper = (helper = helpers.newShareLabel || (depth0 != null ? depth0.newShareLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"newShareLabel","hash":{},"data":data}) : helper))) - + "</span>\n </a>\n </li>\n </ul>\n</div>\n"; -},"useData":true}); -templates['sharedialoglinkshareview_popover_menu_pending'] = template({"1":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li>\n <span class=\"menuitem icon-info\">\n <p>" - + alias5(((helper = (helper = helpers.enforcedPasswordLabel || (depth0 != null ? depth0.enforcedPasswordLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"enforcedPasswordLabel","hash":{},"data":data}) : helper))) - + "</p>\n </span>\n </li>\n <li class=\"linkPassMenu\">\n <span class=\"menuitem\">\n <form autocomplete=\"off\" class=\"enforcedPassForm\">\n <input id=\"enforcedPassText\" required class=\"enforcedPassText\" type=\"password\"\n placeholder=\"" - + alias5(((helper = (helper = helpers.passwordPlaceholder || (depth0 != null ? depth0.passwordPlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordPlaceholder","hash":{},"data":data}) : helper))) - + "\" autocomplete=\"enforcedPassText\" minlength=\"" - + alias5(((helper = (helper = helpers.minPasswordLength || (depth0 != null ? depth0.minPasswordLength : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"minPasswordLength","hash":{},"data":data}) : helper))) - + "\" />\n <input type=\"submit\" value=\" \" class=\"primary icon-checkmark-white\">\n </form>\n </span>\n </li>\n"; -},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return "<div class=\"popovermenu open menu pending\">\n <ul>\n" - + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isPasswordEnforced : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " </ul>\n</div>\n"; -},"useData":true}); -templates['sharedialogresharerinfoview'] = template({"1":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable; - - return "<div class=\"share-note\">" - + container.escapeExpression(((helper = (helper = helpers.shareNote || (depth0 != null ? depth0.shareNote : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"shareNote","hash":{},"data":data}) : helper))) - + "</div>"; -},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "<span class=\"reshare\">\n <div class=\"avatar\" data-userName=\"" - + alias5(((helper = (helper = helpers.reshareOwner || (depth0 != null ? depth0.reshareOwner : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"reshareOwner","hash":{},"data":data}) : helper))) - + "\"></div>\n " - + alias5(((helper = (helper = helpers.sharedByText || (depth0 != null ? depth0.sharedByText : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"sharedByText","hash":{},"data":data}) : helper))) - + "\n</span>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasShareNote : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\n"; -},"useData":true}); -templates['sharedialogshareelistview'] = template({"1":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isShareWithCurrentUser : depth0),{"name":"unless","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); -},"2":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li data-share-id=\"" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" data-share-type=\"" - + alias5(((helper = (helper = helpers.shareType || (depth0 != null ? depth0.shareType : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareType","hash":{},"data":data}) : helper))) - + "\" data-share-with=\"" - + alias5(((helper = (helper = helpers.shareWith || (depth0 != null ? depth0.shareWith : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareWith","hash":{},"data":data}) : helper))) - + "\">\n <div class=\"avatar " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.modSeed : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\" data-username=\"" - + alias5(((helper = (helper = helpers.shareWith || (depth0 != null ? depth0.shareWith : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareWith","hash":{},"data":data}) : helper))) - + "\" data-avatar=\"" - + alias5(((helper = (helper = helpers.shareWithAvatar || (depth0 != null ? depth0.shareWithAvatar : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareWithAvatar","hash":{},"data":data}) : helper))) - + "\" data-displayname=\"" - + alias5(((helper = (helper = helpers.shareWithDisplayName || (depth0 != null ? depth0.shareWithDisplayName : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareWithDisplayName","hash":{},"data":data}) : helper))) - + "\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.modSeed : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "></div>\n <span class=\"username\" title=\"" - + alias5(((helper = (helper = helpers.shareWithTitle || (depth0 != null ? depth0.shareWithTitle : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareWithTitle","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.shareWithDisplayName || (depth0 != null ? depth0.shareWithDisplayName : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareWithDisplayName","hash":{},"data":data}) : helper))) - + "</span>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.canUpdateShareSettings : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " </li>\n"; -},"3":function(container,depth0,helpers,partials,data) { - return "imageplaceholderseed"; -},"5":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "data-seed=\"" - + alias5(((helper = (helper = helpers.shareWith || (depth0 != null ? depth0.shareWith : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareWith","hash":{},"data":data}) : helper))) - + " " - + alias5(((helper = (helper = helpers.shareType || (depth0 != null ? depth0.shareType : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareType","hash":{},"data":data}) : helper))) - + "\""; -},"7":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}); - - return " <span class=\"sharingOptionsGroup\">\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.editPermissionPossible : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " <div tabindex=\"0\" class=\"share-menu\"><span class=\"icon icon-more\"></span>\n " - + ((stack1 = ((helper = (helper = helpers.popoverMenu || (depth0 != null ? depth0.popoverMenu : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(alias2,{"name":"popoverMenu","hash":{},"data":data}) : helper))) != null ? stack1 : "") - + "\n </div>\n </span>\n"; -},"8":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <span>\n <input id=\"canEdit-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"edit\" class=\"permissions checkbox\" />\n <label for=\"canEdit-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.canEditLabel || (depth0 != null ? depth0.canEditLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"canEditLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n"; -},"10":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li data-share-id=\"" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" data-share-type=\"" - + alias5(((helper = (helper = helpers.shareType || (depth0 != null ? depth0.shareType : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareType","hash":{},"data":data}) : helper))) - + "\">\n <div class=\"avatar\" data-username=\"" - + alias5(((helper = (helper = helpers.shareInitiator || (depth0 != null ? depth0.shareInitiator : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareInitiator","hash":{},"data":data}) : helper))) - + "\"></div>\n <span class=\"has-tooltip username\" title=\"" - + alias5(((helper = (helper = helpers.shareInitiator || (depth0 != null ? depth0.shareInitiator : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareInitiator","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.shareInitiatorText || (depth0 != null ? depth0.shareInitiatorText : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareInitiatorText","hash":{},"data":data}) : helper))) - + "</span>\n <span class=\"sharingOptionsGroup\">\n <a href=\"#\" class=\"unshare\"><span class=\"icon-loading-small hidden\"></span><span class=\"icon icon-delete\"></span><span class=\"hidden-visually\">" - + alias5(((helper = (helper = helpers.unshareLabel || (depth0 != null ? depth0.unshareLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"unshareLabel","hash":{},"data":data}) : helper))) - + "</span></a>\n </span>\n </li>\n"; -},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}); - - return "<ul id=\"shareWithList\" class=\"shareWithList\">\n" - + ((stack1 = helpers.each.call(alias2,(depth0 != null ? depth0.sharees : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + ((stack1 = helpers.each.call(alias2,(depth0 != null ? depth0.linkReshares : depth0),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "</ul>\n"; -},"useData":true}); -templates['sharedialogshareelistview_popover_menu'] = template({"1":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return " " - + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.sharePermissionPossible : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " "; -},"2":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return " " - + ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isMailShare : depth0),{"name":"unless","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " "; -},"3":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canShare-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"share\" class=\"permissions checkbox\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasSharePermission : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " data-permissions=\"" - + alias5(((helper = (helper = helpers.sharePermission || (depth0 != null ? depth0.sharePermission : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"sharePermission","hash":{},"data":data}) : helper))) - + "\" />\n <label for=\"canShare-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.canShareLabel || (depth0 != null ? depth0.canShareLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"canShareLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n "; -},"4":function(container,depth0,helpers,partials,data) { - return "checked=\"checked\""; -},"6":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}); - - return " " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.createPermissionPossible : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\n " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.updatePermissionPossible : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\n " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.deletePermissionPossible : depth0),{"name":"if","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\n"; -},"7":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isMailShare : depth0),{"name":"unless","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); -},"8":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canCreate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"create\" class=\"permissions checkbox\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasCreatePermission : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " data-permissions=\"" - + alias5(((helper = (helper = helpers.createPermission || (depth0 != null ? depth0.createPermission : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"createPermission","hash":{},"data":data}) : helper))) - + "\"/>\n <label for=\"canCreate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.createPermissionLabel || (depth0 != null ? depth0.createPermissionLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"createPermissionLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n "; -},"10":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isMailShare : depth0),{"name":"unless","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); -},"11":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canUpdate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"update\" class=\"permissions checkbox\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasUpdatePermission : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " data-permissions=\"" - + alias5(((helper = (helper = helpers.updatePermission || (depth0 != null ? depth0.updatePermission : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"updatePermission","hash":{},"data":data}) : helper))) - + "\"/>\n <label for=\"canUpdate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.updatePermissionLabel || (depth0 != null ? depth0.updatePermissionLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"updatePermissionLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n "; -},"13":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return ((stack1 = helpers.unless.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isMailShare : depth0),{"name":"unless","hash":{},"fn":container.program(14, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); -},"14":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canDelete-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"delete\" class=\"permissions checkbox\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasDeletePermission : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " data-permissions=\"" - + alias5(((helper = (helper = helpers.deletePermission || (depth0 != null ? depth0.deletePermission : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"deletePermission","hash":{},"data":data}) : helper))) - + "\"/>\n <label for=\"canDelete-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.deletePermissionLabel || (depth0 != null ? depth0.deletePermissionLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"deletePermissionLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n "; -},"16":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasCreatePermission : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " <li>\n <span class=\"menuitem\">\n <input id=\"password-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"password\" class=\"password checkbox\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"if","hash":{},"fn":container.program(19, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\" />\n <label for=\"password-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.passwordLabel || (depth0 != null ? depth0.passwordLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li class=\"passwordMenu-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + " " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"unless","hash":{},"fn":container.program(22, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n <span class=\"passwordContainer-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + " icon-passwordmail menuitem\">\n <label for=\"passwordField-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" class=\"hidden-visually\" value=\"" - + alias5(((helper = (helper = helpers.password || (depth0 != null ? depth0.password : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"password","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.passwordLabel || (depth0 != null ? depth0.passwordLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordLabel","hash":{},"data":data}) : helper))) - + "</label>\n <input id=\"passwordField-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" class=\"passwordField\" type=\"password\" placeholder=\"" - + alias5(((helper = (helper = helpers.passwordPlaceholder || (depth0 != null ? depth0.passwordPlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordPlaceholder","hash":{},"data":data}) : helper))) - + "\" value=\"" - + alias5(((helper = (helper = helpers.passwordValue || (depth0 != null ? depth0.passwordValue : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordValue","hash":{},"data":data}) : helper))) - + "\" autocomplete=\"new-password\" />\n <span class=\"icon-loading-small hidden\"></span>\n </span>\n </li>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isTalkEnabled : depth0),{"name":"if","hash":{},"fn":container.program(24, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); -},"17":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li>\n <span class=\"menuitem\">\n <input id=\"secureDrop-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"secureDrop\" class=\"checkbox secureDrop\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.secureDropMode : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " data-permissions=\"" - + alias5(((helper = (helper = helpers.readPermission || (depth0 != null ? depth0.readPermission : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"readPermission","hash":{},"data":data}) : helper))) - + "\"/>\n <label for=\"secureDrop-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.secureDropLabel || (depth0 != null ? depth0.secureDropLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"secureDropLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n"; -},"19":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isPasswordForMailSharesRequired : depth0),{"name":"if","hash":{},"fn":container.program(20, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : ""); -},"20":function(container,depth0,helpers,partials,data) { - return "disabled=\"\""; -},"22":function(container,depth0,helpers,partials,data) { - return "hidden"; -},"24":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li>\n <span class=\"menuitem\">\n <input id=\"passwordByTalk-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"passwordByTalk\" class=\"passwordByTalk checkbox\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isPasswordByTalkSet : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " />\n <label for=\"passwordByTalk-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.passwordByTalkLabel || (depth0 != null ? depth0.passwordByTalkLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordByTalkLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li class=\"passwordByTalkMenu-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + " " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.isPasswordByTalkSet : depth0),{"name":"unless","hash":{},"fn":container.program(22, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n <span class=\"passwordByTalkContainer-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + " icon-passwordtalk menuitem\">\n <label for=\"passwordByTalkField-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" class=\"hidden-visually\" value=\"" - + alias5(((helper = (helper = helpers.password || (depth0 != null ? depth0.password : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"password","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.passwordByTalkLabel || (depth0 != null ? depth0.passwordByTalkLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordByTalkLabel","hash":{},"data":data}) : helper))) - + "</label>\n <input id=\"passwordByTalkField-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" class=\"passwordField\" type=\"password\" placeholder=\"" - + alias5(((helper = (helper = helpers.passwordByTalkPlaceholder || (depth0 != null ? depth0.passwordByTalkPlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordByTalkPlaceholder","hash":{},"data":data}) : helper))) - + "\" value=\"" - + alias5(((helper = (helper = helpers.passwordValue || (depth0 != null ? depth0.passwordValue : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"passwordValue","hash":{},"data":data}) : helper))) - + "\" autocomplete=\"new-password\" />\n <span class=\"icon-loading-small hidden\"></span>\n </span>\n </li>\n"; -},"26":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable; - - return container.escapeExpression(((helper = (helper = helpers.expireDate || (depth0 != null ? depth0.expireDate : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"expireDate","hash":{},"data":data}) : helper))); -},"28":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable; - - return container.escapeExpression(((helper = (helper = helpers.defaultExpireDate || (depth0 != null ? depth0.defaultExpireDate : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"defaultExpireDate","hash":{},"data":data}) : helper))); -},"30":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <li>\n <a href=\"#\" class=\"share-add\">\n <span class=\"icon-loading-small hidden\"></span>\n <span class=\"icon icon-edit\"></span>\n <span>" - + alias5(((helper = (helper = helpers.addNoteLabel || (depth0 != null ? depth0.addNoteLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"addNoteLabel","hash":{},"data":data}) : helper))) - + "</span>\n <input type=\"button\" class=\"share-note-delete icon-delete " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.hasNote : depth0),{"name":"unless","hash":{},"fn":container.program(22, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n </a>\n </li>\n <li class=\"share-note-form " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.hasNote : depth0),{"name":"unless","hash":{},"fn":container.program(22, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n <span class=\"menuitem icon-note\">\n <textarea class=\"share-note\">" - + alias5(((helper = (helper = helpers.shareNote || (depth0 != null ? depth0.shareNote : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareNote","hash":{},"data":data}) : helper))) - + "</textarea>\n <input type=\"submit\" class=\"icon-confirm share-note-submit\" value=\"\" id=\"add-note-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" />\n </span>\n </li>\n"; -},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { - var stack1, helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return "<div class=\"popovermenu bubble hidden menu\">\n <ul>\n " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isResharingAllowed : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isFolder : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isMailShare : depth0),{"name":"if","hash":{},"fn":container.program(16, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " <li>\n <span class=\"menuitem\">\n <input id=\"expireDate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" type=\"checkbox\" name=\"expirationDate\" class=\"expireDate checkbox\" " - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\" />\n <label for=\"expireDate-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.expireDateLabel || (depth0 != null ? depth0.expireDateLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expireDateLabel","hash":{},"data":data}) : helper))) - + "</label>\n </span>\n </li>\n <li class=\"expirationDateMenu-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + " " - + ((stack1 = helpers.unless.call(alias2,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"unless","hash":{},"fn":container.program(22, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "\">\n <span class=\"expirationDateContainer-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + " icon-expiredate menuitem\">\n <label for=\"expirationDatePicker-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" class=\"hidden-visually\" value=\"" - + alias5(((helper = (helper = helpers.expirationDate || (depth0 != null ? depth0.expirationDate : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expirationDate","hash":{},"data":data}) : helper))) - + "\">" - + alias5(((helper = (helper = helpers.expirationLabel || (depth0 != null ? depth0.expirationLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expirationLabel","hash":{},"data":data}) : helper))) - + "</label>\n <input id=\"expirationDatePicker-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "-" - + alias5(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareId","hash":{},"data":data}) : helper))) - + "\" class=\"datepicker\" type=\"text\" placeholder=\"" - + alias5(((helper = (helper = helpers.expirationDatePlaceholder || (depth0 != null ? depth0.expirationDatePlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"expirationDatePlaceholder","hash":{},"data":data}) : helper))) - + "\" value=\"" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(26, data, 0),"inverse":container.program(28, data, 0),"data":data})) != null ? stack1 : "") - + "\" />\n </span>\n </li>\n" - + ((stack1 = helpers["if"].call(alias2,(depth0 != null ? depth0.isNoteAvailable : depth0),{"name":"if","hash":{},"fn":container.program(30, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + " <li>\n <a href=\"#\" class=\"unshare\"><span class=\"icon-loading-small hidden\"></span><span class=\"icon icon-delete\"></span><span>" - + alias5(((helper = (helper = helpers.unshareLabel || (depth0 != null ? depth0.unshareLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"unshareLabel","hash":{},"data":data}) : helper))) - + "</span></a>\n </li>\n </ul>\n</div>\n"; -},"useData":true}); -templates['sharedialogview'] = template({"1":function(container,depth0,helpers,partials,data) { - var helper, alias1=container.propertyIsEnumerable, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", alias5=container.escapeExpression; - - return " <label for=\"shareWith-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"hidden-visually\">" - + alias5(((helper = (helper = helpers.shareLabel || (depth0 != null ? depth0.shareLabel : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"shareLabel","hash":{},"data":data}) : helper))) - + "</label>\n <div class=\"oneline\">\n <input id=\"shareWith-" - + alias5(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"cid","hash":{},"data":data}) : helper))) - + "\" class=\"shareWithField\" type=\"text\" placeholder=\"" - + alias5(((helper = (helper = helpers.sharePlaceholder || (depth0 != null ? depth0.sharePlaceholder : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"sharePlaceholder","hash":{},"data":data}) : helper))) - + "\" />\n <span class=\"shareWithLoading icon-loading-small hidden\"></span>\n <span class=\"shareWithConfirm icon icon-confirm\"></span>\n </div>\n"; -},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) { - var stack1, alias1=container.propertyIsEnumerable; - - return "<div class=\"resharerInfoView subView\"></div>\n" - + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.isSharingAllowed : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "") - + "<div class=\"linkShareView subView\"></div>\n<div class=\"shareeListView subView\"></div>\n<div class=\"loading hidden\" style=\"height: 50px\"></div>\n"; -},"useData":true}); -})(); \ No newline at end of file diff --git a/core/js/tests/specs/shareSpec.js b/core/js/tests/specs/shareSpec.js deleted file mode 100644 index acae9c13e568586dcd568b112a89ad15fc575423..0000000000000000000000000000000000000000 --- a/core/js/tests/specs/shareSpec.js +++ /dev/null @@ -1,371 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2014 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -describe('OC.Share tests', function() { - describe('markFileAsShared', function() { - var $file; - var tooltipStub; - - beforeEach(function() { - tooltipStub = sinon.stub($.fn, 'tooltip'); - $file = $('<tr><td class="filename"><div class="thumbnail"></div><span class="name">File name</span></td></tr>'); - $file.find('.filename').append( - '<span class="fileactions">' + - '<a href="#" class="action action-share" data-action="Share">' + - '<img></img><span> Share</span>' + - '</a>' + - '</span>' - ); - }); - afterEach(function() { - $file = null; - tooltipStub.restore(); - }); - describe('displaying the share owner', function() { - function checkOwner(input, output, title) { - var $action; - - $file.attr('data-share-owner', input); - $file.attr('data-share-owner-id', input); - OC.Share.markFileAsShared($file); - - $action = $file.find('.action-share>span').parent(); - expect($action.text().trim()).toEqual(output); - if (_.isString(title)) { - expect($action.find('.remoteAddress').attr('title')).toEqual(title); - } else { - expect($action.find('.remoteAddress').attr('title')).not.toBeDefined(); - } - expect(tooltipStub.calledOnce).toEqual(true); - tooltipStub.reset(); - } - - it('displays the local share owner with "Shared by" prefix', function() { - checkOwner('User One', 'Shared by User One', null); - }); - it('displays the user name part of a remote share owner', function() { - checkOwner( - 'User One@someserver.com', - 'User One@…', - 'Shared by User One@someserver.com' - ); - checkOwner( - 'User One@someserver.com/', - 'User One@…', - 'Shared by User One@someserver.com' - ); - checkOwner( - 'User One@someserver.com/root/of/owncloud', - 'User One@…', - 'Shared by User One@someserver.com' - ); - }); - it('displays the user name part with domain of a remote share owner', function() { - checkOwner( - 'User One@example.com@someserver.com', - 'User One@example.com', - 'Shared by User One@example.com@someserver.com' - ); - checkOwner( - 'User One@example.com@someserver.com/', - 'User One@example.com', - 'Shared by User One@example.com@someserver.com' - ); - checkOwner( - 'User One@example.com@someserver.com/root/of/owncloud', - 'User One@example.com', - 'Shared by User One@example.com@someserver.com' - ); - }); - }); - - describe('displaying the folder icon', function() { - function checkIcon(expectedImage) { - var imageUrl = OC.TestUtil.getImageUrl($file.find('.filename .thumbnail')); - expectedIcon = OC.imagePath('core', expectedImage); - expect(imageUrl).toEqual(expectedIcon); - } - - it('shows a plain folder icon for non-shared folders', function() { - $file.attr('data-type', 'dir'); - OC.Share.markFileAsShared($file); - - checkIcon('filetypes/folder'); - }); - it('shows a shared folder icon for folders shared with another user', function() { - $file.attr('data-type', 'dir'); - OC.Share.markFileAsShared($file, true); - - checkIcon('filetypes/folder-shared'); - }); - it('shows a shared folder icon for folders shared with the current user', function() { - $file.attr('data-type', 'dir'); - $file.attr('data-share-owner', 'someoneelse'); - $file.attr('data-share-owner-id', 'someoneelse'); - OC.Share.markFileAsShared($file); - - checkIcon('filetypes/folder-shared'); - }); - it('shows a link folder icon for folders shared with link', function() { - $file.attr('data-type', 'dir'); - OC.Share.markFileAsShared($file, false, true); - - checkIcon('filetypes/folder-public'); - }); - it('shows a link folder icon for folders shared with both link and another user', function() { - $file.attr('data-type', 'dir'); - OC.Share.markFileAsShared($file, true, true); - - checkIcon('filetypes/folder-public'); - }); - it('shows a link folder icon for folders reshared with link', function() { - $file.attr('data-type', 'dir'); - $file.attr('data-share-owner', 'someoneelse'); - OC.Share.markFileAsShared($file, false, true); - - checkIcon('filetypes/folder-public'); - }); - it('shows external storage icon if external mount point', function() { - $file.attr('data-type', 'dir'); - $file.attr('data-mountType', 'external'); - OC.Share.markFileAsShared($file, false, false); - - checkIcon('filetypes/folder-external'); - }); - it('shows encrypted icon if encrypted folder', function() { - $file.attr('data-type', 'dir'); - $file.attr('data-e2eencrypted', true); - OC.Share.markFileAsShared($file, false, false); - - checkIcon('filetypes/folder-encrypted'); - }); - }); - - describe('displaying the recipients', function() { - function checkRecipients(input, output, title) { - var $action; - - $file.attr('data-share-recipient-data', JSON.stringify(input)); - OC.Share.markFileAsShared($file, true); - - $action = $file.find('.action-share>span').parent(); - expect($action.text().trim()).toEqual(output); - if (_.isString(title)) { - expect($action.find('.remoteAddress').attr('title')).toEqual(title); - } else if (_.isArray(title)) { - var tooltips = $action.find('.remoteAddress'); - expect(tooltips.length).toEqual(title.length); - - tooltips.each(function(i) { - expect($(this).attr('title')).toEqual(title[i]); - }); - } else { - expect($action.find('.remoteAddress').attr('title')).not.toBeDefined(); - } - expect(tooltipStub.calledOnce).toEqual(true); - tooltipStub.reset(); - } - - it('displays the local share owner as is', function() { - var input = { - 0: { - shareWith: 'User One', - shareWithDisplayName: 'User One' - } - }; - checkRecipients(input, 'Shared with User One', null); - }); - it('displays the user name part of a remote recipient', function() { - var input = { - 0: { - shareWith: 'User One@someserver.com', - shareWithDisplayName: 'User One@someserver.com' - } - }; - checkRecipients( - input, - 'User One@…', - 'Shared with User One@someserver.com' - ); - - input = { - 0: { - shareWith: 'User One@someserver.com/', - shareWithDisplayName: 'User One@someserver.com/' - } - }; - checkRecipients( - input, - 'User One@…', - 'Shared with User One@someserver.com' - ); - - input = { - 0: { - shareWith: 'User One@someserver.com/root/of/nextcloud', - shareWithDisplayName: 'User One@someserver.com/root/of/nextcloud' - } - }; - checkRecipients( - input, - 'User One@…', - 'Shared with User One@someserver.com' - ); - }); - it('displays the user name part with domain of a remote share owner', function() { - var input = { - 0: { - shareWith: 'User One@example.com@someserver.com', - shareWithDisplayName: 'User One@example.com@someserver.com' - } - }; - checkRecipients( - input, - 'User One@example.com', - 'Shared with User One@example.com@someserver.com' - ); - - input = { - 0: { - shareWith: 'User One@example.com@someserver.com/', - shareWithDisplayName: 'User One@example.com@someserver.com/' - } - }; - checkRecipients( - input, - 'User One@example.com', - 'Shared with User One@example.com@someserver.com' - ); - - input = { - 0: { - shareWith: 'User One@example.com@someserver.com/root/of/nextcloud', - shareWithDisplayName: 'User One@example.com@someserver.com/root/of/nextcloud' - } - }; - checkRecipients( - input, - 'User One@example.com', - 'Shared with User One@example.com@someserver.com' - ); - }); - it('display multiple remote recipients', function() { - var input = { - 0: { - shareWith: 'One@someserver.com', - shareWithDisplayName: 'One@someserver.com' - }, - 1: { - shareWith: 'two@otherserver.com', - shareWithDisplayName: 'two@otherserver.com' - } - }; - checkRecipients( - input, - 'One@… two@…', - ['Shared with One@someserver.com', 'Shared with two@otherserver.com'] - ); - - input = { - 0: { - shareWith: 'One@someserver.com/', - shareWithDisplayName: 'One@someserver.com/' - }, - 1: { - shareWith: 'two@someserver.com', - shareWithDisplayName: 'two@someserver.com' - } - }; - checkRecipients( - input, - 'One@… two@…', - ['Shared with One@someserver.com', 'Shared with two@otherserver.com'] - ); - - input = { - 0: { - shareWith: 'One@someserver.com/root/of/nextcloud', - shareWithDisplayName: 'One@someserver.com/root/of/nextcloud' - }, - 1: { - shareWith: 'two@someserver.com', - shareWithDisplayName: 'two@someserver.com' - } - }; - checkRecipients( - input, - 'One@… two@…', - ['Shared with One@someserver.com', 'Shared with two@otherserver.com'] - ); - }); - it('display mixed recipients', function() { - checkRecipients( - { - 0: { - shareWith: 'One', - shareWithDisplayName: 'One' - }, - 1: { - shareWith: 'two@otherserver.com', - shareWithDisplayName: 'two@otherserver.com' - } - }, - 'Shared with One two@…', - ['Shared with two@otherserver.com'] - ); - }); - it('display multiple with divergent displaynames', function() { - var recipients = { - 0: { - shareWith: 'One', - shareWithDisplayName: 'Yoko Ono', - _output: 'Shared with Yoko Ono' - }, - 1: { - shareWith: 'two@otherserver.com', - shareWithDisplayName: 'two@othererver.com', - _output: 'two@…' - }, - 2: { - shareWith: 'Three', - shareWithDisplayName: 'Green, Mina', - _output: 'Shared with Green, Mina' - } - }; - - // we cannot assume the locale, also because PhantomJS has a bug. - var sortArray = _.toArray(recipients) - .sort(function(a, b) { - return a.shareWithDisplayName.localeCompare(b.shareWithDisplayName); - }); - var sortedOutput = _.map(sortArray, function(recipient) { - return recipient._output; - }).join(' '); - - checkRecipients( - recipients, - sortedOutput, - ['Shared with two@otherserver.com'] - ); - }); - }); - }); -}); diff --git a/core/js/tests/specs/sharedialoglinkshareview.js b/core/js/tests/specs/sharedialoglinkshareview.js deleted file mode 100644 index 39bf256d33409075ac7a91444e3ace5a18c7c45a..0000000000000000000000000000000000000000 --- a/core/js/tests/specs/sharedialoglinkshareview.js +++ /dev/null @@ -1,349 +0,0 @@ -/** - * - * @copyright Copyright (c) 2015, Tom Needham (tom@owncloud.com) - * @copyright Copyright (c) 2017, Daniel Calviño Sánchez (danxuliu@gmail.com) - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -describe('OC.Share.ShareDialogLinkShareView', function () { - - var configModel; - var shareModel; - var view; - - beforeEach(function () { - - var fileInfoModel = new OCA.Files.FileInfoModel({ - id: 123, - name: 'shared_file_name.txt', - path: '/subdir', - size: 100, - mimetype: 'text/plain', - permissions: OC.PERMISSION_ALL, - sharePermissions: OC.PERMISSION_ALL - }); - - var attributes = { - itemType: fileInfoModel.isDirectory() ? 'folder' : 'file', - itemSource: fileInfoModel.get('id'), - possiblePermissions: OC.PERMISSION_ALL, - permissions: OC.PERMISSION_ALL - }; - - configModel = new OC.Share.ShareConfigModel({ - enforcePasswordForPublicLink: false, - isResharingAllowed: true, - isDefaultExpireDateEnabled: false, - isDefaultExpireDateEnforced: false, - defaultExpireDate: 7 - }); - - sinon.stub(configModel, 'isShareWithLinkAllowed'); - - shareModel = new OC.Share.ShareItemModel(attributes, { - configModel: configModel, - fileInfoModel: fileInfoModel - }); - - view = new OC.Share.ShareDialogLinkShareView({ - configModel: configModel, - model: shareModel - }); - - }); - - afterEach(function () { - view.remove(); - configModel.isShareWithLinkAllowed.restore(); - }); - - describe('hide download', function () { - - var $hideDownloadCheckbox; - var $workingIcon; - - beforeEach(function () { - // Needed to render the view - configModel.isShareWithLinkAllowed.returns(true); - - shareModel.set({ - linkShares: [{ - id: 123 - }] - }); - view.render(); - - $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); - $workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small'); - - sinon.stub(shareModel, 'saveLinkShare'); - - expect($workingIcon.hasClass('hidden')).toBeTruthy(); - }); - - afterEach(function () { - shareModel.saveLinkShare.restore(); - }); - - it('is shown if the share is a file', function() { - expect($hideDownloadCheckbox.length).toBeTruthy(); - }); - - it('is not shown if the share is a folder', function() { - shareModel.fileInfoModel.set('mimetype', 'httpd/unix-directory'); - - // Setting the item type also triggers the rendering - shareModel.set({ - itemType: 'folder' - }); - - $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); - - expect($hideDownloadCheckbox.length).toBeTruthy(); - }); - - it('checkbox is checked when the setting is enabled', function () { - shareModel.set({ - linkShares: [{ - id: 123, - hideDownload: true - }] - }); - view.render(); - - $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); - - expect($hideDownloadCheckbox.is(':checked')).toEqual(true); - }); - - it('checkbox is not checked when the setting is disabled', function () { - expect($hideDownloadCheckbox.is(':checked')).toEqual(false); - }); - - it('enables the setting if clicked when unchecked', function () { - // Simulate the click by checking the checkbox and then triggering - // the "change" event. - $hideDownloadCheckbox.prop('checked', true); - $hideDownloadCheckbox.change(); - - expect($workingIcon.hasClass('hidden')).toBeFalsy(); - expect(shareModel.saveLinkShare.withArgs({ hideDownload: true, cid: 123 }).calledOnce).toBeTruthy(); - }); - - it('disables the setting if clicked when checked', function () { - shareModel.set({ - linkShares: [{ - id: 123, - hideDownload: true - }] - }); - view.render(); - - $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox'); - $workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small'); - - // Simulate the click by unchecking the checkbox and then triggering - // the "change" event. - $hideDownloadCheckbox.prop('checked', false); - $hideDownloadCheckbox.change(); - - expect($workingIcon.hasClass('hidden')).toBeFalsy(); - expect(shareModel.saveLinkShare.withArgs({ hideDownload: false, cid: 123 }).calledOnce).toBeTruthy(); - }); - - }); - - describe('onPasswordEntered', function () { - - var $passwordText; - var $workingIcon; - - beforeEach(function () { - - // Needed to render the view - configModel.isShareWithLinkAllowed.returns(true); - - shareModel.set({ - linkShares: [{ - id: 123, - password: 'password' - }] - }); - view.render(); - - $passwordText = view.$el.find('.linkPassText'); - $workingIcon = view.$el.find('.linkPassMenu .icon-loading-small'); - - sinon.stub(shareModel, 'saveLinkShare'); - - expect($passwordText.hasClass('hidden')).toBeFalsy(); - expect($workingIcon.hasClass('hidden')).toBeTruthy(); - - $passwordText.val('myPassword'); - }); - - afterEach(function () { - shareModel.saveLinkShare.restore(); - }); - - it('shows the working icon when called', function () { - view.onPasswordEntered({target: view.$el.find('.linkPassText')}); - - expect($workingIcon.hasClass('hidden')).toBeFalsy(); - expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy(); - }); - - it('hides the working icon when saving the password succeeds', function () { - view.onPasswordEntered({target: view.$el.find('.linkPassText')}); - - expect($workingIcon.hasClass('hidden')).toBeFalsy(); - expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy(); - - shareModel.saveLinkShare.yieldTo("complete", [shareModel]); - - expect($workingIcon.hasClass('hidden')).toBeTruthy(); - }); - - it('hides the working icon when saving the password fails', function () { - view.onPasswordEntered({target: view.$el.find('.linkPassText')}); - - expect($workingIcon.hasClass('hidden')).toBeFalsy(); - expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy(); - - shareModel.saveLinkShare.yieldTo("complete", [shareModel]); - shareModel.saveLinkShare.yieldTo("error", [shareModel, "The error message"]); - - expect($workingIcon.hasClass('hidden')).toBeTruthy(); - }); - - }); - - describe('protect password by Talk', function () { - - var $passwordByTalkCheckbox; - var $workingIcon; - - beforeEach(function () { - // Needed to render the view - configModel.isShareWithLinkAllowed.returns(true); - - // "Enable" Talk - OC.appswebroots['spreed'] = OC.getRootPath() + '/apps/files/'; - - shareModel.set({ - linkShares: [{ - id: 123, - password: 'password' - }] - }); - view.render(); - - $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); - $workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small'); - - sinon.stub(shareModel, 'saveLinkShare'); - - expect($workingIcon.hasClass('hidden')).toBeTruthy(); - }); - - afterEach(function () { - shareModel.saveLinkShare.restore(); - }); - - it('is shown if Talk is enabled and there is a password set', function() { - expect($passwordByTalkCheckbox.length).toBeTruthy(); - }); - - it('is not shown if Talk is enabled but there is no password set', function() { - // Changing the password value also triggers the rendering - shareModel.set({ - linkShares: [{ - id: 123 - }] - }); - - $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); - - expect($passwordByTalkCheckbox.length).toBeFalsy(); - }); - - it('is not shown if there is a password set but Talk is not enabled', function() { - // "Disable" Talk - delete OC.appswebroots['spreed']; - - view.render(); - - $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); - - expect($passwordByTalkCheckbox.length).toBeFalsy(); - }); - - it('checkbox is checked when the setting is enabled', function () { - shareModel.set({ - linkShares: [{ - id: 123, - password: 'password', - sendPasswordByTalk: true - }] - }); - view.render(); - - $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); - - expect($passwordByTalkCheckbox.is(':checked')).toEqual(true); - }); - - it('checkbox is not checked when the setting is disabled', function () { - expect($passwordByTalkCheckbox.is(':checked')).toEqual(false); - }); - - it('enables the setting if clicked when unchecked', function () { - // Simulate the click by checking the checkbox and then triggering - // the "change" event. - $passwordByTalkCheckbox.prop('checked', true); - $passwordByTalkCheckbox.change(); - - expect($workingIcon.hasClass('hidden')).toBeFalsy(); - expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: true, cid: 123 }).calledOnce).toBeTruthy(); - }); - - it('disables the setting if clicked when checked', function () { - shareModel.set({ - linkShares: [{ - id: 123, - password: 'password', - sendPasswordByTalk: true - }] - }); - view.render(); - - $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox'); - $workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small'); - - // Simulate the click by unchecking the checkbox and then triggering - // the "change" event. - $passwordByTalkCheckbox.prop('checked', false); - $passwordByTalkCheckbox.change(); - - expect($workingIcon.hasClass('hidden')).toBeFalsy(); - expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: false, cid: 123 }).calledOnce).toBeTruthy(); - }); - - }); - -}); diff --git a/core/js/tests/specs/sharedialogshareelistview.js b/core/js/tests/specs/sharedialogshareelistview.js deleted file mode 100644 index 7a679603ae881ab83f2b173f858d4f2f19259456..0000000000000000000000000000000000000000 --- a/core/js/tests/specs/sharedialogshareelistview.js +++ /dev/null @@ -1,242 +0,0 @@ -/** - * ownCloud - * - * @author Tom Needham - * @copyright 2015 Tom Needham <tom@owncloud.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. - * - */ - -describe('OC.Share.ShareDialogShareeListView', function () { - - var oldCurrentUser; - var fileInfoModel; - var configModel; - var shareModel; - var listView; - var updateShareStub; - - beforeEach(function () { - /* jshint camelcase:false */ - oldAppConfig = _.extend({}, OC.appConfig.core); - OC.appConfig.core.enforcePasswordForPublicLink = false; - - fileInfoModel = new OCA.Files.FileInfoModel({ - id: 123, - name: 'shared_file_name.txt', - path: '/subdir', - size: 100, - mimetype: 'text/plain', - permissions: 31, - sharePermissions: 31 - }); - - var attributes = { - itemType: fileInfoModel.isDirectory() ? 'folder' : 'file', - itemSource: fileInfoModel.get('id'), - possiblePermissions: 31, - permissions: 31 - }; - - shareModel = new OC.Share.ShareItemModel(attributes, { - configModel: configModel, - fileInfoModel: fileInfoModel - }); - - configModel = new OC.Share.ShareConfigModel({ - enforcePasswordForPublicLink: false, - isResharingAllowed: true, - isDefaultExpireDateEnabled: false, - isDefaultExpireDateEnforced: false, - defaultExpireDate: 7 - }); - - listView = new OC.Share.ShareDialogShareeListView({ - configModel: configModel, - model: shareModel - }); - - // required for proper event propagation when simulating clicks in some cases (jquery bugs) - $('#testArea').append(listView.$el); - - shareModel.set({ - linkShares: [] - }); - - oldCurrentUser = OC.currentUser; - OC.currentUser = 'user0'; - updateShareStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'updateShare'); - }); - - afterEach(function () { - OC.currentUser = oldCurrentUser; - /* jshint camelcase:false */ - OC.appConfig.core = oldAppConfig; - listView.remove(); - updateShareStub.restore(); - }); - - describe('Sets correct initial checkbox state', function () { - - it('marks edit box as unchecked for file shares without edit permissions', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'file' - }]); - listView.render(); - expect(listView.$el.find("input[name='edit']").is(':not(:checked)')).toEqual(true); - }); - - it('marks edit box as checked for file shares', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1 | OC.PERMISSION_UPDATE, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'file' - }]); - listView.render(); - expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true); - }); - - it('marks edit box as indeterminate when only some permissions are given', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1 | OC.PERMISSION_UPDATE, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'folder' - }]); - shareModel.set('itemType', 'folder'); - listView.render(); - expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true); - }); - - it('marks edit box as indeterminate when only some permissions are given for sharee with special characters', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1 | OC.PERMISSION_UPDATE, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user _.@-\'', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'folder' - }]); - shareModel.set('itemType', 'folder'); - listView.render(); - expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true); - }); - - it('Checks edit box when all permissions are given', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'folder' - }]); - shareModel.set('itemType', 'folder'); - listView.render(); - expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true); - }); - - it('Checks edit box when all permissions are given for sharee with special characters', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_UPDATE | OC.PERMISSION_DELETE, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user _.@-\'', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'folder' - }]); - shareModel.set('itemType', 'folder'); - listView.render(); - expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true); - }); - }); - describe('Manages checkbox events correctly', function () { - it('Checks cruds boxes when edit box checked', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - }]); - shareModel.set('itemType', 'folder'); - listView.render(); - listView.$el.find("input[name='edit']").click(); - expect(listView.$el.find("input[name='update']").is(':checked')).toEqual(true); - expect(updateShareStub.calledOnce).toEqual(true); - }); - - it('marks edit box as indeterminate when some of create/update/delete are checked', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'folder' - }]); - shareModel.set('itemType', 'folder'); - listView.render(); - listView.$el.find("input[name='update']").click(); - expect(listView.$el.find("input[name='edit']").is(':indeterminate')).toEqual(true); - expect(updateShareStub.calledOnce).toEqual(true); - }); - - it('Checks edit box when all of create/update/delete are checked', function () { - shareModel.set('shares', [{ - id: 100, - item_source: 123, - permissions: 1 | OC.PERMISSION_CREATE | OC.PERMISSION_DELETE, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One', - uid_owner: OC.getCurrentUser().uid, - itemType: 'folder' - }]); - shareModel.set('itemType', 'folder'); - listView.render(); - listView.$el.find("input[name='update']").click(); - expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true); - expect(updateShareStub.calledOnce).toEqual(true); - }); - }); - -}); diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js deleted file mode 100644 index 5ae478006439fecba86bc89be11f17e6c7fa9389..0000000000000000000000000000000000000000 --- a/core/js/tests/specs/sharedialogviewSpec.js +++ /dev/null @@ -1,2600 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2015 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/* global sinon, OC */ -describe('OC.Share.ShareDialogView', function() { - var $container; - var oldConfig; - var oldAppConfig; - var autocompleteStub; - var avatarStub; - var placeholderStub; - var oldCurrentUser; - var saveLinkShareStub; - - var fetchStub; - - var configModel; - var shareModel; - var fileInfoModel; - var dialog; - - beforeEach(function() { - // horrible parameters - $('#testArea').append('<input id="allowShareWithLink" type="hidden" value="yes">'); - $container = $('#shareContainer'); - oldConfig = OC.config; - OC.config['sharing.maxAutocompleteResults'] = 0; - /* jshint camelcase:false */ - oldAppConfig = _.extend({}, OC.appConfig.core); - OC.appConfig.core.enforcePasswordForPublicLink = false; - - fetchStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'fetch'); - saveLinkShareStub = sinon.stub(OC.Share.ShareItemModel.prototype, 'saveLinkShare'); - - fileInfoModel = new OCA.Files.FileInfoModel({ - id: 123, - name: 'shared_file_name.txt', - path: '/subdir', - size: 100, - mimetype: 'text/plain', - permissions: 31, - sharePermissions: 31 - }); - - var attributes = { - itemType: fileInfoModel.isDirectory() ? 'folder' : 'file', - itemSource: fileInfoModel.get('id'), - possiblePermissions: 31, - permissions: 31 - }; - configModel = new OC.Share.ShareConfigModel({ - enforcePasswordForPublicLink: false, - isResharingAllowed: true, - isDefaultExpireDateEnabled: false, - isDefaultExpireDateEnforced: false, - defaultExpireDate: 7 - }); - shareModel = new OC.Share.ShareItemModel(attributes, { - configModel: configModel, - fileInfoModel: fileInfoModel - }); - dialog = new OC.Share.ShareDialogView({ - configModel: configModel, - model: shareModel - }); - - // required for proper event propagation when simulating clicks in some cases (jquery bugs) - $('#testArea').append(dialog.$el); - - // triggers rendering - shareModel.set({ - shares: [], - linkShares: [] - }); - - autocompleteStub = sinon.stub($.fn, 'autocomplete').callsFake(function() { - // dummy container with the expected attributes - if (!$(this).length) { - // simulate the real autocomplete that returns - // nothing at all when no element is specified - // (and potentially break stuff) - return null; - } - var $el = $('<div></div>').data('ui-autocomplete', {}); - return $el; - }); - - avatarStub = sinon.stub($.fn, 'avatar'); - placeholderStub = sinon.stub($.fn, 'imageplaceholder'); - - oldCurrentUser = OC.currentUser; - OC.currentUser = 'user0'; - }); - afterEach(function() { - OC.currentUser = oldCurrentUser; - OC.config = oldConfig; - /* jshint camelcase:false */ - OC.appConfig.core = oldAppConfig; - - dialog.remove(); - fetchStub.restore(); - saveLinkShareStub.restore(); - - autocompleteStub.restore(); - avatarStub.restore(); - placeholderStub.restore(); - }); - describe('Share with link', function() { - // TODO: test ajax calls - // TODO: test password field visibility (whenever enforced or not) - it('update password on enter', function() { - $('#allowShareWithLink').val('yes'); - - dialog.model.set({ - linkShares: [{ - id: 123 - }] - }); - dialog.render(); - - // Enable password and enter password - dialog.$el.find('[name=showPassword]').click(); - dialog.$el.find('.linkPassText').focus(); - dialog.$el.find('.linkPassText').val('foo'); - dialog.$el.find('.linkPassText').trigger(new $.Event('keyup', {keyCode: 13})); - - expect(saveLinkShareStub.calledOnce).toEqual(true); - expect(saveLinkShareStub.firstCall.args[0]).toEqual({ - cid: 123, - password: 'foo' - }); - }); - it('update password on submit', function() { - $('#allowShareWithLink').val('yes'); - - dialog.model.set({ - linkShares: [{ - id: 123 - }] - }); - dialog.render(); - - // Enable password and enter password - dialog.$el.find('[name=showPassword]').click(); - dialog.$el.find('.linkPassText').focus(); - dialog.$el.find('.linkPassText').val('foo'); - dialog.$el.find('.linkPassText + .icon-confirm').click(); - - expect(saveLinkShareStub.calledOnce).toEqual(true); - expect(saveLinkShareStub.firstCall.args[0]).toEqual({ - cid: 123, - password: 'foo' - }); - }); - it('shows add share with link button when allowed', function() { - $('#allowShareWithLink').val('yes'); - - dialog.render(); - - expect(dialog.$el.find('.new-share').length).toEqual(1); - }); - it('does not show add share with link button when not allowed', function() { - $('#allowShareWithLink').val('no'); - - dialog.render(); - - expect(dialog.$el.find('.new-share').length).toEqual(0); - expect(dialog.$el.find('.shareWithField').length).toEqual(1); - }); - it('shows populated link share when a link share exists', function() { - // this is how the OC.Share class does it... - var link = parent.location.protocol + '//' + location.host + - OC.generateUrl('/s/') + 'thetoken'; - shareModel.set({ - linkShares: [{ - id: 123, - url: link - }] - }); - - dialog.render(); - - expect(dialog.$el.find('.share-menu .icon-more').length).toEqual(1); - expect(dialog.$el.find('.linkText').val()).toEqual(link); - }); - it('autofocus link text when clicked', function() { - $('#allowShareWithLink').val('yes'); - - dialog.model.set({ - linkShares: [{ - id: 123 - }] - }); - dialog.render(); - - var focusStub = sinon.stub($.fn, 'focus'); - var selectStub = sinon.stub($.fn, 'select'); - dialog.$el.find('.linkText').click(); - - expect(focusStub.calledOnce).toEqual(true); - expect(selectStub.calledOnce).toEqual(true); - - focusStub.restore(); - selectStub.restore(); - }); - }); - describe('check for avatar', function() { - beforeEach(function() { - shareModel.set({ - reshare: { - share_type: OC.Share.SHARE_TYPE_USER, - uid_owner: 'owner', - displayname_owner: 'Owner', - permissions: 31 - }, - shares: [{ - id: 100, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One' - },{ - id: 101, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_GROUP, - share_with: 'group', - share_with_displayname: 'group' - },{ - id: 102, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_REMOTE, - share_with: 'foo@bar.com/baz', - share_with_displayname: 'foo@bar.com/baz' - },{ - id: 103, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_CIRCLE, - share_with: 'circle-0', - share_with_displayname: 'Circle (Personal circle, user0)', - share_with_avatar: 'path/to/the/avatar' - },{ - id: 104, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_CIRCLE, - share_with: 'circle-1', - share_with_displayname: 'Circle (Public circle, user0)', - }] - }); - }); - - describe('avatars enabled', function() { - beforeEach(function() { - avatarStub.reset(); - dialog.render(); - }); - - it('test correct function calls', function() { - expect(avatarStub.calledThrice).toEqual(true); - expect(placeholderStub.callCount).toEqual(4); - expect(dialog.$('.shareWithList').children().length).toEqual(6); - expect(dialog.$('.avatar').length).toEqual(7); - }); - - it('test avatar owner', function() { - var args = avatarStub.getCall(0).args; - expect(args.length).toEqual(2); - expect(args[0]).toEqual('owner'); - }); - - it('test avatar user', function() { - var args = avatarStub.getCall(1).args; - expect(args.length).toEqual(6); - expect(args[0]).toEqual('user1'); - expect(args[5]).toEqual('User One'); - }); - - it('test avatar for groups', function() { - var args = placeholderStub.getCall(0).args; - expect(args.length).toEqual(1); - expect(args[0]).toEqual('group ' + OC.Share.SHARE_TYPE_GROUP); - }); - - it('test avatar for remotes', function() { - var args = placeholderStub.getCall(1).args; - expect(args.length).toEqual(1); - expect(args[0]).toEqual('foo@bar.com/baz ' + OC.Share.SHARE_TYPE_REMOTE); - }); - - it('test avatar for circle', function() { - var avatarElement = dialog.$('.avatar').eq(5); - expect(avatarElement.css('background')).toContain('path/to/the/avatar'); - }); - - it('test avatar for circle without avatar', function() { - var args = avatarStub.getCall(2).args; - expect(args.length).toEqual(6); - // Note that "data-username" is set to "circle-{shareIndex}", - // not to the "shareWith" field. - expect(args[0]).toEqual('circle-4'); - expect(args[5]).toEqual('Circle (Public circle, user0)'); - }); - }); - }); - describe('get suggestions', function() { - it('no matches', function() { - var doneStub = sinon.stub(); - var failStub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true, - } - } - }); - - expect(doneStub.called).toEqual(false); - expect(failStub.called).toEqual(false); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(doneStub, [{ - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], [], false, true); - expect(failStub.called).toEqual(false); - }); - - it('single partial match', function() { - var doneStub = sinon.stub(); - var failStub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bobby', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'imbob' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true, - } - } - }); - - expect(doneStub.called).toEqual(false); - expect(failStub.called).toEqual(false); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(doneStub, - [{ - 'label': 'bobby', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [], - false, - true - ); - expect(failStub.called).toEqual(false); - }); - it('single exact match', function() { - var doneStub = sinon.stub(); - var failStub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true, - } - } - }); - - expect(doneStub.called).toEqual(false); - expect(failStub.called).toEqual(false); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(doneStub, - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }], - false, - true - ); - expect(failStub.called).toEqual(false); - }); - it('mixed matches', function() { - var doneStub = sinon.stub(); - var failStub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group1' - } - } - ], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bobby', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'imbob' - } - }, - { - 'label': 'bob the second', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user2' - } - } - ], - 'groups': [ - { - 'label': 'bobfans', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'fans' - } - } - ], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true - } - } - }); - - expect(doneStub.called).toEqual(false); - expect(failStub.called).toEqual(false); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(doneStub, - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, { - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'} - }, { - 'label': 'bobby', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} - }, { - 'label': 'bob the second', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user2'} - }, { - 'label': 'bobfans', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'fans'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, { - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'} - }], - false, - true - ); - expect(failStub.called).toEqual(false); - }); - - it('capped mixed matches', function() { - OC.config['sharing.maxAutocompleteResults'] = 3; - var doneStub = sinon.stub(); - var failStub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group1' - } - } - ], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bobby', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'imbob' - } - }, - { - 'label': 'bob the second', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user2' - } - } - ], - 'groups': [ - { - 'label': 'bobfans', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'fans' - } - } - ], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true - } - } - }); - - expect(doneStub.called).toEqual(false); - expect(failStub.called).toEqual(false); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(doneStub, - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, { - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'} - }, { - 'label': 'bobby', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} - }, { - 'label': 'bob the second', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user2'} - }, { - 'label': 'bobfans', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'fans'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, { - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group1'} - }], - true, - true - ); - expect(failStub.called).toEqual(false); - }); - - it('does not send a request to the server again for the same parameters', function() { - var doneStub = sinon.stub(); - var failStub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true - } - } - }); - - expect(doneStub.called).toEqual(false); - expect(failStub.called).toEqual(false); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - expect(doneStub.calledWithExactly( - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }], - false, - true - )).toEqual(true); - expect(failStub.called).toEqual(false); - - var done2Stub = sinon.stub(); - var fail2Stub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(done2Stub).fail(fail2Stub); - - expect(doneStub.calledOnce).toEqual(true); - expect(failStub.called).toEqual(false); - - expect(done2Stub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(doneStub, - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }], - false, - true - ); - expect(fail2Stub.called).toEqual(false); - }); - - it('sends a request to the server again for the same parameters if the calls are not consecutive', function() { - var doneStub = sinon.stub(); - var failStub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(doneStub).fail(failStub); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true - } - } - }); - - expect(doneStub.called).toEqual(false); - expect(failStub.called).toEqual(false); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(doneStub, - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }], - false, - true - ); - expect(failStub.called).toEqual(false); - - var done2Stub = sinon.stub(); - var fail2Stub = sinon.stub(); - - dialog._getSuggestions('bob', 108, shareModel).done(done2Stub).fail(fail2Stub); - - expect(done2Stub.called).toEqual(false); - expect(fail2Stub.called).toEqual(false); - - fakeServer.requests[1].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(done2Stub.calledOnce).toEqual(true); - expect(fail2Stub.called).toEqual(false); - - var done3Stub = sinon.stub(); - var fail3Stub = sinon.stub(); - - dialog._getSuggestions('bob', 42, shareModel).done(done3Stub).fail(fail3Stub); - - expect(done3Stub.called).toEqual(false); - expect(fail3Stub.called).toEqual(false); - - fakeServer.requests[2].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(doneStub.calledOnce).toEqual(true); - expect(failStub.called).toEqual(false); - expect(done2Stub.calledOnce).toEqual(true); - expect(fail2Stub.called).toEqual(false); - - expect(done3Stub.calledOnce).toEqual(true); - sinon.assert.calledWithExactly(done3Stub, - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, - { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }], - [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }], - false, - true - ); - expect(fail3Stub.called).toEqual(false); - }); - }); - describe('autocompletion of users', function() { - var showTemporaryNotificationStub; - - beforeEach(function() { - showTemporaryNotificationStub = sinon.stub(OC.Notification, 'showTemporary'); - }); - - afterEach(function() { - showTemporaryNotificationStub.restore(); - }); - - describe('triggers autocomplete display and focus with data when ajax search succeeds', function () { - it('users', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bobby', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'imbob' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - sinon.assert.calledWithExactly(response, [{ - 'label': 'bob', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'user1'} - }, { - 'label': 'bobby', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} - }, { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }]); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('groups', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'group'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [ - { - 'label': 'group', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group' - } - } - ], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [ - { - 'label': 'group2', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group2' - } - } - ], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'lookupEnabled': true - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - sinon.assert.calledWithExactly(response, [{ - 'label': 'group', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group'} - }, { - 'label': 'group2', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'} - }, { - label: t('core', 'Search globally'), - value: {}, - lookup: true - }]); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('remotes', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'foo@bar.com/baz'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [ - { - 'label': 'foo@bar.com/baz', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_REMOTE, - 'shareWith': 'foo@bar.com/baz' - } - } - ], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [ - { - 'label': 'foo@bar.com/baz2', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_REMOTE, - 'shareWith': 'foo@bar.com/baz2' - } - } - ], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'foo@bar.com/baz', - 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz'} - }, { - 'label': 'foo@bar.com/baz2', - 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz2'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('emails', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'foo@bar.com'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'emails': [ - { - 'label': 'foo@bar.com', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_EMAIL, - 'shareWith': 'foo@bar.com' - } - } - ] - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'emails': [ - { - 'label': 'foo@bar.com2', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_EMAIL, - 'shareWith': 'foo@bar.com2' - } - } - ] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'foo@bar.com', - 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com'} - }, { - 'label': 'foo@bar.com2', - 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com2'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('circles', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'CircleName'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'circles': [ - { - 'label': 'CircleName (type, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId' - } - }, - { - 'label': 'CircleName (type2, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId2' - } - } - ] - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'circles': [ - { - 'label': 'CircleName2 (type, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId3' - } - } - ] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'CircleName (type, owner)', - 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId'} - }, { - 'label': 'CircleName (type2, owner)', - 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'} - }, { - 'label': 'CircleName2 (type, owner)', - 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId3'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - }); - - describe('filter out', function() { - it('the current user', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': 0, - 'shareWith': OC.currentUser - } - }, - { - 'label': 'bobby', - 'value': { - 'shareType': 0, - 'shareWith': 'imbob' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'bobby', - 'value': {'shareType': 0, 'shareWith': 'imbob'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('the share owner', function () { - shareModel.set({ - reshare: { - uid_owner: 'user1' - }, - shares: [], - permissions: OC.PERMISSION_READ - }); - - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': 0, - 'shareWith': 'user1' - } - }, - { - 'label': 'bobby', - 'value': { - 'shareType': 0, - 'shareWith': 'imbob' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'bobby', - 'value': {'shareType': 0, 'shareWith': 'imbob'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - describe('already shared with', function () { - beforeEach(function() { - shareModel.set({ - reshare: {}, - shares: [{ - id: 100, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One' - },{ - id: 101, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_GROUP, - share_with: 'group', - share_with_displayname: 'group' - },{ - id: 102, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_REMOTE, - share_with: 'foo@bar.com/baz', - share_with_displayname: 'foo@bar.com/baz' - },{ - id: 103, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_EMAIL, - share_with: 'foo@bar.com', - share_with_displayname: 'foo@bar.com' - },{ - id: 104, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_CIRCLE, - share_with: 'shortId', - share_with_displayname: 'CircleName (type, owner)' - }] - }); - }); - - it('users', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bo'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - }, - { - 'label': 'bobby', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'imbob' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'bobby', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('users (exact)', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bobby', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'imbob' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'bobby', - 'value': {'shareType': OC.Share.SHARE_TYPE_USER, 'shareWith': 'imbob'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('groups', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'grou'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [ - { - 'label': 'group', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group' - } - }, - { - 'label': 'group2', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group2' - } - } - ], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'group2', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('groups (exact)', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'group'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [ - { - 'label': 'group', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group' - } - } - ], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [ - { - 'label': 'group2', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group2' - } - } - ], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'group2', - 'value': {'shareType': OC.Share.SHARE_TYPE_GROUP, 'shareWith': 'group2'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('remotes', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'foo'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [ - { - 'label': 'foo@bar.com/baz', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_REMOTE, - 'shareWith': 'foo@bar.com/baz' - } - }, - { - 'label': 'foo2@bar.com/baz', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_REMOTE, - 'shareWith': 'foo2@bar.com/baz' - } - } - ], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'foo2@bar.com/baz', - 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo2@bar.com/baz'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('remotes (exact)', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'foo@bar.com/baz'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [ - { - 'label': 'foo@bar.com/baz', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_REMOTE, - 'shareWith': 'foo@bar.com/baz' - } - } - ], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [ - { - 'label': 'foo@bar.com/baz2', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_REMOTE, - 'shareWith': 'foo@bar.com/baz2' - } - } - ], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'foo@bar.com/baz2', - 'value': {'shareType': OC.Share.SHARE_TYPE_REMOTE, 'shareWith': 'foo@bar.com/baz2'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('emails', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'foo'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'emails': [] - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'lookup': [], - 'remote_groups': [], - 'emails': [ - { - 'label': 'foo@bar.com', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_EMAIL, - 'shareWith': 'foo@bar.com' - } - }, - { - 'label': 'foo2@bar.com', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_EMAIL, - 'shareWith': 'foo2@bar.com' - } - } - ] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'foo2@bar.com', - 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo2@bar.com'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('emails (exact)', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'foo@bar.com'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'emails': [ - { - 'label': 'foo@bar.com', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_EMAIL, - 'shareWith': 'foo@bar.com' - } - } - ] - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'emails': [ - { - 'label': 'foo@bar.com2', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_EMAIL, - 'shareWith': 'foo@bar.com2' - } - } - ] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'foo@bar.com2', - 'value': {'shareType': OC.Share.SHARE_TYPE_EMAIL, 'shareWith': 'foo@bar.com2'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('circles', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'CircleNam'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'circles': [] - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'circles': [ - { - 'label': 'CircleName (type, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId' - } - }, - { - 'label': 'CircleName (type2, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId2' - } - } - ] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'CircleName (type2, owner)', - 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - - it('circles (exact)', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'CircleName'}, response); - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'circles': [ - { - 'label': 'CircleName (type, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId' - } - }, - { - 'label': 'CircleName (type2, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId2' - } - } - ] - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [], - 'circles': [ - { - 'label': 'CircleName2 (type, owner)', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_CIRCLE, - 'shareWith': 'shortId3' - } - } - ] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.calledWithExactly([{ - 'label': 'CircleName (type2, owner)', - 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId2'} - }, { - 'label': 'CircleName2 (type, owner)', - 'value': {'shareType': OC.Share.SHARE_TYPE_CIRCLE, 'shareWith': 'shortId3'} - }])).toEqual(true); - expect(autocompleteStub.calledWith("option", "autoFocus", true)).toEqual(true); - }); - }); - }); - - it('throws a notification for a successful ajax call with failure content', function () { - dialog.render(); - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); - var jsonData = JSON.stringify({ - 'ocs' : { - 'meta' : { - 'status': 'failure', - 'statuscode': 400, - 'message': 'error message' - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - expect(response.called).toEqual(false); - expect(showTemporaryNotificationStub.calledOnce).toEqual(true); - expect(showTemporaryNotificationStub.firstCall.args[0]).toContain('error message'); - }); - - it('throws a notification when the ajax search lookup fails', function () { - dialog.render(); - dialog.autocompleteHandler({term: 'bob'}, sinon.stub()); - fakeServer.requests[0].respond(500); - expect(showTemporaryNotificationStub.calledOnce).toEqual(true); - }); - - describe('renders the autocomplete elements', function() { - it('renders a group element', function() { - dialog.render(); - var el = dialog.autocompleteRenderItem( - $("<ul></ul>"), - {label: "1", value: { shareType: OC.Share.SHARE_TYPE_GROUP }} - ); - expect(el.is('li')).toEqual(true); - expect(el.hasClass('group')).toEqual(true); - }); - - it('renders a remote element', function() { - dialog.render(); - var el = dialog.autocompleteRenderItem( - $("<ul></ul>"), - {label: "1", value: { shareType: OC.Share.SHARE_TYPE_REMOTE }} - ); - expect(el.is('li')).toEqual(true); - expect(el.hasClass('user')).toEqual(true); - }); - }); - - it('calls addShare after selection', function() { - dialog.render(); - - var shareWith = $('.shareWithField')[0]; - var $shareWith = $(shareWith); - var addShareStub = sinon.stub(shareModel, 'addShare'); - var autocompleteOptions = autocompleteStub.getCall(0).args[0]; - autocompleteOptions.select(new $.Event('select', {target: shareWith}), { - item: { - label: 'User Two', - value: { - shareType: OC.Share.SHARE_TYPE_USER, - shareWith: 'user2' - } - } - }); - - expect(addShareStub.calledOnce).toEqual(true); - expect(addShareStub.firstCall.args[0]).toEqual({ - shareType: OC.Share.SHARE_TYPE_USER, - shareWith: 'user2' - }); - - //Input is locked - expect($shareWith.val()).toEqual('User Two'); - expect($shareWith.attr('disabled')).toEqual('disabled'); - - //Callback is called - addShareStub.firstCall.args[1].success(); - - //Input is unlocked - expect($shareWith.val()).toEqual(''); - expect($shareWith.attr('disabled')).toEqual(undefined); - - addShareStub.restore(); - }); - - it('calls addShare after selection and fail to share', function() { - dialog.render(); - - var shareWith = $('.shareWithField')[0]; - var $shareWith = $(shareWith); - var addShareStub = sinon.stub(shareModel, 'addShare'); - var autocompleteOptions = autocompleteStub.getCall(0).args[0]; - autocompleteOptions.select(new $.Event('select', {target: shareWith}), { - item: { - label: 'User Two', - value: { - shareType: OC.Share.SHARE_TYPE_USER, - shareWith: 'user2' - } - } - }); - - expect(addShareStub.calledOnce).toEqual(true); - expect(addShareStub.firstCall.args[0]).toEqual({ - shareType: OC.Share.SHARE_TYPE_USER, - shareWith: 'user2' - }); - - //Input is locked - expect($shareWith.val()).toEqual('User Two'); - expect($shareWith.attr('disabled')).toEqual('disabled'); - - //Callback is called - addShareStub.firstCall.args[1].error(); - - //Input is unlocked - expect($shareWith.val()).toEqual('User Two'); - expect($shareWith.attr('disabled')).toEqual(undefined); - - addShareStub.restore(); - }); - - it('hides the loading icon when all the pending operations finish', function() { - dialog.render(); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - - var response = sinon.stub(); - dialog.autocompleteHandler({term: 'bob'}, response); - dialog.autocompleteHandler({term: 'bobby'}, response); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); - - fakeServer.requests[1].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - }); - }); - describe('confirm share', function() { - var addShareStub; - var tooltipStub; - var showTemporaryNotificationStub; - - beforeEach(function() { - addShareStub = sinon.stub(shareModel, 'addShare'); - - tooltipStub = sinon.stub($.fn, 'tooltip').callsFake(function() { - return $('<div></div>'); - }); - - showTemporaryNotificationStub = sinon.stub(OC.Notification, 'showTemporary'); - - dialog.render(); - }); - - afterEach(function() { - addShareStub.restore(); - tooltipStub.restore(); - showTemporaryNotificationStub.restore(); - }); - - it('sets the appropriate UI state while waiting to get the suggestions', function() { - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.callCount).toEqual(1); - expect(typeof autocompleteStub.firstCall.args[0]).toEqual('object'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - - dialog.$el.find('.shareWithField').val('bob'); - - dialog._confirmShare(); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); - expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); - expect(autocompleteStub.calledWith('close')).toEqual(true); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - }); - - it('calls addShare with the only suggestion', function() { - dialog.$el.find('.shareWithField').val('bob'); - - dialog._confirmShare(); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - // Ensure that the UI is not restored before adding the share - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); - expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - - expect(addShareStub.calledOnce).toEqual(true); - expect(addShareStub.firstCall.args[0]).toEqual({ - shareType: OC.Share.SHARE_TYPE_USER, - shareWith: 'user1' - }); - - // "yield" and "callArg" from SinonJS can not be used, as the - // callback is a property not in the first argument. - addShareStub.firstCall.args[1]['success'].apply(shareModel); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - expect(dialog.$el.find('.shareWithField').val()).toEqual(''); - }); - - it('handles a failure to share', function() { - expect(showTemporaryNotificationStub.called).toEqual(false); - - dialog.$el.find('.shareWithField').val('bob'); - - dialog._confirmShare(); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - // Ensure that the UI is not restored before adding the share - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(false); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(true); - expect(autocompleteStub.lastCall.args[0]).toEqual('disable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - - expect(addShareStub.calledOnce).toEqual(true); - expect(addShareStub.firstCall.args[0]).toEqual({ - shareType: OC.Share.SHARE_TYPE_USER, - shareWith: 'user1' - }); - - // "yield" and "callArg" from SinonJS can not be used, as the - // callback is a property not in the first argument. - addShareStub.firstCall.args[1]['error'].apply(shareModel); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - - expect(showTemporaryNotificationStub.calledOnce).toEqual(true); - }); - - it('restores UI if there are no matches at all', function() { - dialog.$el.find('.shareWithField').val('bob'); - - dialog._confirmShare(); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'lookup': [], - 'remote_groups': [], - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(addShareStub.called).toEqual(false); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - - // No explicit tooltip is shown; it is automatically shown when the - // autocomplete is activated again and it finds no matches. - expect(tooltipStub.lastCall.args[0]).not.toEqual('show'); - }); - - it('shows tooltip if there are matches but no exact matches', function() { - dialog.$el.find('.shareWithField').val('bo'); - - dialog._confirmShare(); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(addShareStub.called).toEqual(false); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bo'); - }); - - it('shows tooltip if there is more than one exact match', function() { - dialog.$el.find('.shareWithField').val('bob'); - - dialog._confirmShare(); - - var jsonData = JSON.stringify({ - 'ocs': { - 'meta': { - 'status': 'success', - 'statuscode': 100, - 'message': null - }, - 'data': { - 'exact': { - 'users': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_USER, - 'shareWith': 'user1' - } - } - ], - 'groups': [ - { - 'label': 'bob', - 'value': { - 'shareType': OC.Share.SHARE_TYPE_GROUP, - 'shareWith': 'group1' - } - } - ], - 'remotes': [], - 'remote_groups': [], - }, - 'users': [], - 'groups': [], - 'remotes': [], - 'remote_groups': [], - 'lookup': [] - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(addShareStub.called).toEqual(false); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - }); - - it('throws a notification for a successful ajax call with failure content', function () { - dialog.$el.find('.shareWithField').val('bob'); - - dialog._confirmShare(); - - var jsonData = JSON.stringify({ - 'ocs' : { - 'meta' : { - 'status': 'failure', - 'statuscode': 400, - 'message': 'error message' - } - } - }); - fakeServer.requests[0].respond( - 200, - {'Content-Type': 'application/json'}, - jsonData - ); - - expect(addShareStub.called).toEqual(false); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - - expect(showTemporaryNotificationStub.called).toEqual(false); - }); - - it('throws a notification when the ajax search lookup fails', function () { - dialog.$el.find('.shareWithField').val('bob'); - - dialog._confirmShare(); - - fakeServer.requests[0].respond(500); - - expect(addShareStub.called).toEqual(false); - - expect(dialog.$el.find('.shareWithLoading').hasClass('hidden')).toEqual(true); - expect(dialog.$el.find('.shareWithConfirm').hasClass('hidden')).toEqual(false); - expect(autocompleteStub.lastCall.args[0]).toEqual('enable'); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(false); - expect(dialog.$el.find('.shareWithField').val()).toEqual('bob'); - - expect(showTemporaryNotificationStub.called).toEqual(false); - }); - }); - describe('reshare permissions', function() { - it('does not show sharing options when sharing not allowed', function() { - shareModel.set({ - reshare: {}, - shares: [], - permissions: OC.PERMISSION_READ - }); - dialog.render(); - expect(dialog.$el.find('.shareWithField').prop('disabled')).toEqual(true); - }); - it('shows reshare owner for single user share', function() { - shareModel.set({ - reshare: { - uid_owner: 'user1', - displayname_owner: 'User One', - share_type: OC.Share.SHARE_TYPE_USER - }, - shares: [], - permissions: OC.PERMISSION_READ - }); - dialog.render(); - expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(1); - expect(dialog.$el.find('.resharerInfoView .reshare').text().trim()).toEqual('Shared with you by User One'); - }); - it('shows reshare owner for single user share', function() { - shareModel.set({ - reshare: { - uid_owner: 'user1', - displayname_owner: 'User One', - share_with: 'group2', - share_with_displayname: 'Group Two', - share_type: OC.Share.SHARE_TYPE_GROUP - }, - shares: [], - permissions: OC.PERMISSION_READ - }); - dialog.render(); - expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(1); - expect(dialog.$el.find('.resharerInfoView .reshare').text().trim()).toEqual('Shared with you and the group Group Two by User One'); - }); - it('does not show reshare owner if owner is current user', function() { - shareModel.set({ - reshare: { - uid_owner: OC.currentUser - }, - shares: [], - permissions: OC.PERMISSION_READ - }); - dialog.render(); - expect(dialog.$el.find('.resharerInfoView .reshare').length).toEqual(0); - }); - }); -}); diff --git a/core/js/tests/specs/shareitemmodelSpec.js b/core/js/tests/specs/shareitemmodelSpec.js deleted file mode 100644 index d08f23f08423c3259750ca5d53fcaeacd4944e7f..0000000000000000000000000000000000000000 --- a/core/js/tests/specs/shareitemmodelSpec.js +++ /dev/null @@ -1,1026 +0,0 @@ -/** -* ownCloud -* -* @author Vincent Petry -* @copyright 2015 Vincent Petry <pvince81@owncloud.com> -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/* global OC */ - -describe('OC.Share.ShareItemModel', function() { - var fetchSharesStub, fetchReshareStub; - var fetchSharesDeferred, fetchReshareDeferred; - var fileInfoModel, configModel, model; - var oldCurrentUser; - var capsSpec; - - beforeEach(function() { - oldCurrentUser = OC.currentUser; - - fetchSharesDeferred = new $.Deferred(); - fetchSharesStub = sinon.stub(OC.Share.ShareItemModel.prototype, '_fetchShares') - .returns(fetchSharesDeferred.promise()); - fetchReshareDeferred = new $.Deferred(); - fetchReshareStub = sinon.stub(OC.Share.ShareItemModel.prototype, '_fetchReshare') - .returns(fetchReshareDeferred.promise()); - - fileInfoModel = new OCA.Files.FileInfoModel({ - id: 123, - name: 'shared_file_name.txt', - path: '/subdir', - size: 100, - mimetype: 'text/plain', - permissions: 31, - sharePermissions: 31 - }); - - var attributes = { - itemType: fileInfoModel.isDirectory() ? 'folder' : 'file', - itemSource: fileInfoModel.get('id'), - possiblePermissions: fileInfoModel.get('sharePermissions') - }; - configModel = new OC.Share.ShareConfigModel(); - model = new OC.Share.ShareItemModel(attributes, { - configModel: configModel, - fileInfoModel: fileInfoModel - }); - capsSpec = sinon.stub(OC, 'getCapabilities'); - capsSpec.returns({ - 'files_sharing': { - 'default_permissions': OC.PERMISSION_ALL - } - }); - }); - afterEach(function() { - capsSpec.restore(); - if (fetchSharesStub) { - fetchSharesStub.restore(); - } - if (fetchReshareStub) { - fetchReshareStub.restore(); - } - OC.currentUser = oldCurrentUser; - }); - - function makeOcsResponse(data) { - return [{ - ocs: { - data: data - } - }]; - } - - describe('Fetching and parsing', function() { - it('fetches both outgoing shares and the current incoming share', function() { - model.fetch(); - - expect(fetchSharesStub.calledOnce).toEqual(true); - expect(fetchReshareStub.calledOnce).toEqual(true); - }); - it('fetches shares for the current path', function() { - fetchSharesStub.restore(); - - model._fetchShares(); - - expect(fakeServer.requests.length).toEqual(1); - expect(fakeServer.requests[0].method).toEqual('GET'); - expect(fakeServer.requests[0].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1', 2) + - 'shares?format=json&path=%2Fsubdir%2Fshared_file_name.txt&reshares=true' - ); - - fetchSharesStub = null; - }); - it('fetches reshare for the current path', function() { - fetchReshareStub.restore(); - - model._fetchReshare(); - - expect(fakeServer.requests.length).toEqual(1); - expect(fakeServer.requests[0].method).toEqual('GET'); - expect(fakeServer.requests[0].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1', 2) + - 'shares?format=json&path=%2Fsubdir%2Fshared_file_name.txt&shared_with_me=true' - ); - - fetchReshareStub = null; - }); - it('populates attributes with parsed response', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([ - { - share_type: OC.Share.SHARE_TYPE_USER, - uid_owner: 'owner', - displayname_owner: 'Owner', - permissions: 31 - } - ])); - fetchSharesDeferred.resolve(makeOcsResponse([ - { - id: 100, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - share_with_displayname: 'User One' - }, { - id: 101, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_GROUP, - share_with: 'group', - share_with_displayname: 'group' - }, { - id: 102, - item_source: 123, - permissions: 31, - share_type: OC.Share.SHARE_TYPE_REMOTE, - share_with: 'foo@bar.com/baz', - share_with_displayname: 'foo@bar.com/baz' - - }, { - displayname_owner: 'root', - expiration: null, - file_source: 123, - file_target: '/folder', - id: 20, - item_source: '123', - item_type: 'folder', - mail_send: '0', - parent: null, - path: '/folder', - permissions: OC.PERMISSION_READ, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - stime: 1403884258, - storage: 1, - token: 'tehtoken', - uid_owner: 'root', - hide_download: 1, - send_password_by_talk: true - } - ])); - - OC.currentUser = 'root'; - - model.fetch(); - - var shares = model.get('shares'); - expect(shares.length).toEqual(3); - expect(shares[0].id).toEqual(100); - expect(shares[0].permissions).toEqual(31); - expect(shares[0].share_type).toEqual(OC.Share.SHARE_TYPE_USER); - expect(shares[0].share_with).toEqual('user1'); - expect(shares[0].share_with_displayname).toEqual('User One'); - - var linkShares = model.get('linkShares'); - expect(linkShares.length).toEqual(1); - var linkShare = linkShares[0]; - expect(linkShare.hideDownload).toEqual(true); - expect(linkShare.sendPasswordByTalk).toEqual(true); - - // TODO: check more attributes - }); - it('groups reshare info into a single item', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([ - { - id: '1', - share_type: OC.Share.SHARE_TYPE_USER, - uid_owner: 'owner', - displayname_owner: 'Owner', - share_with: 'root', - share_with_displayname: 'Wurzel', - permissions: 1 - }, - { - id: '2', - share_type: OC.Share.SHARE_TYPE_GROUP, - uid_owner: 'owner', - displayname_owner: 'Owner', - share_with: 'group1', - permissions: 15 - }, - { - id: '3', - share_type: OC.Share.SHARE_TYPE_GROUP, - uid_owner: 'owner', - displayname_owner: 'Owner', - share_with: 'group1', - permissions: 17 - } - ])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - OC.currentUser = 'root'; - - model.fetch(); - - var reshare = model.get('reshare'); - // max permissions - expect(reshare.permissions).toEqual(31); - // user share has higher priority - expect(reshare.share_type).toEqual(OC.Share.SHARE_TYPE_USER); - expect(reshare.share_with).toEqual('root'); - expect(reshare.share_with_displayname).toEqual('Wurzel'); - expect(reshare.id).toEqual('1'); - - expect(model.getReshareWith()).toEqual('root'); - expect(model.getReshareWithDisplayName()).toEqual('Wurzel'); - }); - it('does not parse link share when for a different file', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([{ - displayname_owner: 'root', - expiration: null, - file_source: 456, - file_target: '/folder', - id: 20, - item_source: '456', - item_type: 'folder', - mail_send: '0', - parent: null, - path: '/folder', - permissions: OC.PERMISSION_READ, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - stime: 1403884258, - storage: 1, - token: 'tehtoken', - uid_owner: 'root' - }] - )); - - model.fetch(); - - var shares = model.get('shares'); - // remaining share appears in this list - expect(shares.length).toEqual(1); - - var linkShares = model.get('linkShares'); - expect(linkShares.length).toEqual(0); - }); - it('parses correct link share when a nested link share exists along with parent one', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([{ - displayname_owner: 'root', - expiration: '2015-10-12 00:00:00', - file_source: 123, - file_target: '/folder', - id: 20, - item_source: '123', - item_type: 'file', - mail_send: '0', - parent: null, - path: '/folder', - permissions: OC.PERMISSION_READ, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - stime: 1403884258, - storage: 1, - token: 'tehtoken', - uid_owner: 'root', - hide_download: 0, - send_password_by_talk: false - }, { - displayname_owner: 'root', - expiration: '2015-10-15 00:00:00', - file_source: 456, - file_target: '/file_in_folder.txt', - id: 21, - item_source: '456', - item_type: 'file', - mail_send: '0', - parent: null, - path: '/folder/file_in_folder.txt', - permissions: OC.PERMISSION_READ, - share_type: OC.Share.SHARE_TYPE_LINK, - share_with: null, - stime: 1403884509, - storage: 1, - token: 'anothertoken', - uid_owner: 'root', - hide_download: 1, - send_password_by_talk: true - }] - )); - OC.currentUser = 'root'; - model.fetch(); - - var shares = model.get('shares'); - // the parent share remains in the list - expect(shares.length).toEqual(1); - - var linkShares = model.get('linkShares'); - expect(linkShares.length).toEqual(1); - var linkShare = linkShares[0]; - expect(linkShare.token).toEqual('tehtoken'); - expect(linkShare.hideDownload).toEqual(false); - expect(linkShare.sendPasswordByTalk).toEqual(false); - - // TODO: check child too - }); - it('reduces reshare permissions to the ones from the original share', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([{ - id: 123, - permissions: OC.PERMISSION_READ, - uid_owner: 'user1' - }])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - model.fetch(); - - // no resharing allowed - expect(model.get('permissions')).toEqual(OC.PERMISSION_READ); - }); - it('reduces reshare permissions to possible permissions', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([{ - id: 123, - permissions: OC.PERMISSION_ALL, - uid_owner: 'user1' - }])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - model.fileInfoModel.set('permissions', OC.PERMISSION_READ); - model.fetch(); - - // no resharing allowed - expect(model.get('permissions')).toEqual(OC.PERMISSION_READ); - }); - it('allows owner to share their own share when they are also the recipient', function() { - OC.currentUser = 'user1'; - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - model.fetch(); - - // sharing still allowed - expect(model.get('permissions') & OC.PERMISSION_SHARE).toEqual(OC.PERMISSION_SHARE); - }); - it('properly parses integer values when the server is in the mood of returning ints as string', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([{ - displayname_owner: 'root', - expiration: '2015-10-12 00:00:00', - file_source: '123', - file_target: '/folder', - id: '20', - item_source: '123', - item_type: 'file', - mail_send: '0', - parent: '999', - path: '/folder', - permissions: '' + OC.PERMISSION_READ, - share_type: '' + OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - stime: '1403884258', - storage: '1', - token: 'tehtoken', - uid_owner: 'root' - }] - )); - - model.fetch(); - - var shares = model.get('shares'); - expect(shares.length).toEqual(1); - - var share = shares[0]; - expect(share.id).toEqual(20); - expect(share.file_source).toEqual(123); - expect(share.file_target).toEqual('/folder'); - expect(share.item_source).toEqual(123); - expect(share.item_type).toEqual('file'); - expect(share.displayname_owner).toEqual('root'); - expect(share.mail_send).toEqual(0); - expect(share.parent).toEqual(999); - expect(share.path).toEqual('/folder'); - expect(share.permissions).toEqual(OC.PERMISSION_READ); - expect(share.share_type).toEqual(OC.Share.SHARE_TYPE_USER); - expect(share.share_with).toEqual('user1'); - expect(share.stime).toEqual(1403884258); - expect(share.expiration).toEqual('2015-10-12 00:00:00'); - }); - }); - describe('hasUserShares', function() { - it('returns false when no user shares exist', function() { - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - model.fetch(); - - expect(model.hasUserShares()).toEqual(false); - }); - it('returns true when user shares exist on the current item', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([{ - id: 1, - share_type: OC.Share.SHARE_TYPE_USER, - share_with: 'user1', - item_source: '123' - }])); - - model.fetch(); - - expect(model.hasUserShares()).toEqual(true); - }); - it('returns true when group shares exist on the current item', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([{ - id: 1, - share_type: OC.Share.SHARE_TYPE_GROUP, - share_with: 'group1', - item_source: '123' - }])); - - model.fetch(); - - expect(model.hasUserShares()).toEqual(true); - }); - it('returns false when share exist on parent item', function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([{ - id: 1, - share_type: OC.Share.SHARE_TYPE_GROUP, - share_with: 'group1', - item_source: '111' - }])); - - model.fetch(); - - expect(model.hasUserShares()).toEqual(false); - }); - }); - - describe('Util', function() { - it('parseTime should properly parse strings', function() { - - _.each([ - [ '123456', 123456], - [ 123456 , 123456], - ['0123456', 123456], - ['abcdefg', null], - ['0x12345', null], - [ '', null], - ], function(value) { - expect(OC.Share.ShareItemModel.prototype._parseTime(value[0])).toEqual(value[1]); - }); - - }); - }); - - - describe('share permissions', function() { - beforeEach(function() { - OC.appConfig.core.resharingAllowed = true; - }); - - /** - * Tests sharing with the given possible permissions - * - * @param {int} possiblePermissions - * @return {int} permissions sent to the server - */ - function testWithPermissions(possiblePermissions) { - model.set({ - permissions: possiblePermissions, - possiblePermissions: possiblePermissions - }); - model.addShare({ - shareType: OC.Share.SHARE_TYPE_USER, - shareWith: 'user2' - }); - - var requestBody = OC.parseQueryString(_.last(fakeServer.requests).requestBody); - return parseInt(requestBody.permissions, 10); - } - - describe('regular sharing', function() { - it('shares with given permissions with default config', function() { - configModel.set('isResharingAllowed', true); - model.set({ - reshare: {}, - shares: [] - }); - expect( - testWithPermissions(OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE) - ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE); - expect( - testWithPermissions(OC.PERMISSION_READ | OC.PERMISSION_SHARE) - ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_SHARE); - }); - it('removes share permission when not allowed', function() { - configModel.set('isResharingAllowed', false); - model.set({ - reshare: {}, - shares: [] - }); - expect( - testWithPermissions(OC.PERMISSION_READ | OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE) - ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_UPDATE); - }); - it('automatically adds READ permission even when not specified', function() { - configModel.set('isResharingAllowed', false); - model.set({ - reshare: {}, - shares: [] - }); - expect( - testWithPermissions(OC.PERMISSION_UPDATE | OC.PERMISSION_SHARE) - ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_UPDATE); - }); - it('uses default permissions from capabilities', function() { - capsSpec.returns({ - 'files_sharing': { - 'default_permissions': OC.PERMISSION_READ | OC.PERMISSION_CREATE | OC.PERMISSION_SHARE - } - }); - configModel.set('isResharingAllowed', true); - model.set({ - reshare: {}, - shares: [] - }); - expect( - testWithPermissions(OC.PERMISSION_ALL) - ).toEqual(OC.PERMISSION_READ | OC.PERMISSION_CREATE | OC.PERMISSION_SHARE); - }); - }); - }); - - describe('saveLinkShare', function() { - var addShareStub; - var updateShareStub; - - beforeEach(function() { - addShareStub = sinon.stub(model, 'addShare'); - updateShareStub = sinon.stub(model, 'updateShare'); - }); - afterEach(function() { - addShareStub.restore(); - updateShareStub.restore(); - }); - - it('creates a new share if no link share exists', function() { - model.set({ - linkShares: [ - ] - }); - - model.saveLinkShare(); - - expect(addShareStub.calledOnce).toEqual(true); - expect(addShareStub.firstCall.args[0]).toEqual({ - hideDownload: false, - password: '', - passwordChanged: false, - sendPasswordByTalk: false, - permissions: OC.PERMISSION_READ, - expireDate: '', - shareType: OC.Share.SHARE_TYPE_LINK - }); - expect(updateShareStub.notCalled).toEqual(true); - }); - it('creates a new share with default expiration date', function() { - var clock = sinon.useFakeTimers(Date.UTC(2015, 6, 17, 1, 2, 0, 3)); - configModel.set({ - isDefaultExpireDateEnabled: true, - defaultExpireDate: 7 - }); - model.set({ - linkShares: [ - ] - }); - - model.saveLinkShare(); - - expect(addShareStub.calledOnce).toEqual(true); - expect(addShareStub.firstCall.args[0]).toEqual({ - hideDownload: false, - password: '', - passwordChanged: false, - sendPasswordByTalk: false, - permissions: OC.PERMISSION_READ, - expireDate: '2015-07-24 00:00:00', - shareType: OC.Share.SHARE_TYPE_LINK - }); - expect(updateShareStub.notCalled).toEqual(true); - clock.restore(); - }); - it('updates link share if it exists', function() { - model.set({ - linkShares: [{ - id: 123 - }] - }); - - model.saveLinkShare({ - cid: 123, - password: 'test' - }); - - expect(addShareStub.notCalled).toEqual(true); - expect(updateShareStub.calledOnce).toEqual(true); - expect(updateShareStub.firstCall.args[0]).toEqual(123); - expect(updateShareStub.firstCall.args[1]).toEqual({ - cid: 123, - password: 'test' - }); - }); - it('forwards error message on add', function() { - var errorStub = sinon.stub(); - model.set({ - linkShares: [ - ] - }, { - }); - - model.saveLinkShare({ - }, { - error: errorStub - }); - - addShareStub.yieldTo('error', 'Some error message'); - - expect(errorStub.calledOnce).toEqual(true); - expect(errorStub.lastCall.args[0]).toEqual('Some error message'); - }); - it('forwards error message on update', function() { - var errorStub = sinon.stub(); - model.set({ - linkShares: [{ - id: 123 - }] - }, { - }); - - model.saveLinkShare({ - cid: 123, - password: 'test' - }, { - error: errorStub - }); - - updateShareStub.yieldTo('error', 'Some error message'); - - expect(errorStub.calledOnce).toEqual(true); - expect(errorStub.lastCall.args[0]).toEqual('Some error message'); - }); - }); - describe('creating shares', function() { - it('sends POST method to endpoint with passed values', function() { - model.addShare({ - shareType: OC.Share.SHARE_TYPE_GROUP, - shareWith: 'group1' - }); - - expect(fakeServer.requests.length).toEqual(1); - expect(fakeServer.requests[0].method).toEqual('POST'); - expect(fakeServer.requests[0].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1', 2) + - 'shares?format=json' - ); - expect(OC.parseQueryString(fakeServer.requests[0].requestBody)).toEqual({ - path: '/subdir/shared_file_name.txt', - permissions: '' + OC.PERMISSION_READ, - shareType: '' + OC.Share.SHARE_TYPE_GROUP, - shareWith: 'group1' - }); - }); - it('calls complete handler before refreshing the model', function() { - var completeStub = sinon.stub(); - model.addShare({ - shareType: OC.Share.SHARE_TYPE_GROUP, - shareWith: 'group1' - }, { - complete: completeStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify({ }) - ); - - expect(completeStub.calledOnce).toEqual(true); - expect(completeStub.lastCall.args[0]).toEqual(model); - - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - expect(completeStub.calledOnce).toEqual(true); - }); - it('calls success handler after refreshing the model', function() { - var successStub = sinon.stub(); - model.addShare({ - shareType: OC.Share.SHARE_TYPE_GROUP, - shareWith: 'group1' - }, { - success: successStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify({ }) - ); - - expect(successStub.called).toEqual(false); - - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - expect(successStub.calledOnce).toEqual(true); - expect(successStub.lastCall.args[0]).toEqual(model); - }); - it('calls complete handler before error handler', function() { - var completeStub = sinon.stub(); - var errorStub = sinon.stub(); - model.addShare({ - shareType: OC.Share.SHARE_TYPE_GROUP, - shareWith: 'group1' - }, { - complete: completeStub, - error: errorStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 400, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - ocs: { - meta: { - message: 'Some error message' - } - } - }) - ); - - expect(completeStub.calledOnce).toEqual(true); - expect(completeStub.lastCall.args[0]).toEqual(model); - expect(errorStub.calledOnce).toEqual(true); - expect(completeStub.calledBefore(errorStub)).toEqual(true); - }); - it('calls error handler with error message', function() { - var errorStub = sinon.stub(); - model.addShare({ - shareType: OC.Share.SHARE_TYPE_GROUP, - shareWith: 'group1' - }, { - error: errorStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 400, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - ocs: { - meta: { - message: 'Some error message' - } - } - }) - ); - - expect(errorStub.calledOnce).toEqual(true); - expect(errorStub.lastCall.args[0]).toEqual(model); - expect(errorStub.lastCall.args[1]).toEqual('Some error message'); - }); - }); - describe('updating shares', function() { - it('sends PUT method to endpoint with passed values', function() { - model.updateShare(123, { - permissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE - }); - - expect(fakeServer.requests.length).toEqual(1); - expect(fakeServer.requests[0].method).toEqual('PUT'); - expect(fakeServer.requests[0].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1', 2) + - 'shares/123?format=json' - ); - expect(OC.parseQueryString(fakeServer.requests[0].requestBody)).toEqual({ - permissions: '' + (OC.PERMISSION_READ | OC.PERMISSION_SHARE) - }); - }); - it('calls complete handler before refreshing the model', function() { - var completeStub = sinon.stub(); - model.updateShare(123, { - permissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE - }, { - complete: completeStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify({ }) - ); - - expect(completeStub.calledOnce).toEqual(true); - expect(completeStub.lastCall.args[0]).toEqual(model); - - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - expect(completeStub.calledOnce).toEqual(true); - }); - it('calls success handler after refreshing the model', function() { - var successStub = sinon.stub(); - model.updateShare(123, { - permissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE - }, { - success: successStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 200, - { 'Content-Type': 'application/json' }, - JSON.stringify({ }) - ); - - expect(successStub.called).toEqual(false); - - fetchReshareDeferred.resolve(makeOcsResponse([])); - fetchSharesDeferred.resolve(makeOcsResponse([])); - - expect(successStub.calledOnce).toEqual(true); - expect(successStub.lastCall.args[0]).toEqual(model); - }); - it('calls complete handler before error handler', function() { - var completeStub = sinon.stub(); - var errorStub = sinon.stub(); - model.updateShare(123, { - permissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE - }, { - complete: completeStub, - error: errorStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 400, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - ocs: { - meta: { - message: 'Some error message' - } - } - }) - ); - - expect(completeStub.calledOnce).toEqual(true); - expect(completeStub.lastCall.args[0]).toEqual(model); - expect(errorStub.calledOnce).toEqual(true); - expect(completeStub.calledBefore(errorStub)).toEqual(true); - }); - it('calls error handler with error message', function() { - var errorStub = sinon.stub(); - model.updateShare(123, { - permissions: OC.PERMISSION_READ | OC.PERMISSION_SHARE - }, { - error: errorStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 400, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - ocs: { - meta: { - message: 'Some error message' - } - } - }) - ); - - expect(errorStub.calledOnce).toEqual(true); - expect(errorStub.lastCall.args[0]).toEqual(model); - expect(errorStub.lastCall.args[1]).toEqual('Some error message'); - }); - }); - describe('removing shares', function() { - it('sends DELETE method to endpoint with share id', function() { - model.removeShare(123); - - expect(fakeServer.requests.length).toEqual(1); - expect(fakeServer.requests[0].method).toEqual('DELETE'); - expect(fakeServer.requests[0].url).toEqual( - OC.linkToOCS('apps/files_sharing/api/v1', 2) + - 'shares/123?format=json' - ); - }); - it('calls error handler with error message', function() { - var errorStub = sinon.stub(); - model.removeShare(123, { - error: errorStub - }); - - expect(fakeServer.requests.length).toEqual(1); - fakeServer.requests[0].respond( - 400, - { 'Content-Type': 'application/json' }, - JSON.stringify({ - ocs: { - meta: { - message: 'Some error message' - } - } - }) - ); - - expect(errorStub.calledOnce).toEqual(true); - expect(errorStub.lastCall.args[1]).toEqual('Some error message'); - }); - }); - - describe('getShareTypes', function() { - - var dataProvider = [ - [ - ], - [ - OC.Share.SHARE_TYPE_USER, - OC.Share.SHARE_TYPE_USER, - ], - [ - OC.Share.SHARE_TYPE_USER, - OC.Share.SHARE_TYPE_GROUP, - OC.Share.SHARE_TYPE_LINK, - OC.Share.SHARE_TYPE_REMOTE - ], - [ - OC.Share.SHARE_TYPE_USER, - OC.Share.SHARE_TYPE_GROUP, - OC.Share.SHARE_TYPE_GROUP, - OC.Share.SHARE_TYPE_LINK, - OC.Share.SHARE_TYPE_LINK, - OC.Share.SHARE_TYPE_REMOTE, - OC.Share.SHARE_TYPE_REMOTE, - OC.Share.SHARE_TYPE_REMOTE - ], - [ - OC.Share.SHARE_TYPE_LINK, - OC.Share.SHARE_TYPE_LINK, - OC.Share.SHARE_TYPE_USER - ] - ]; - - _.each(dataProvider, function testCase(shareTypes, i) { - it('returns set of share types for case ' + i, function() { - /* jshint camelcase: false */ - fetchReshareDeferred.resolve(makeOcsResponse([])); - - var id = 100; - var shares = _.map(shareTypes, function(shareType) { - return { - id: id++, - item_source: 123, - permissions: 31, - share_type: shareType, - uid_owner: 'root' - }; - }); - - var expectedResult = _.uniq(shareTypes).sort(); - - fetchSharesDeferred.resolve(makeOcsResponse(shares)); - - OC.currentUser = 'root'; - - model.fetch(); - - expect(model.getShareTypes().sort()).toEqual(expectedResult); - }); - }); - }); -}); - diff --git a/core/webpack.js b/core/webpack.js index b421e12a56713276a750a4eba1cda81e82da581a..9404c354ebb4d848da2f481ac9a0c205a5e56759 100644 --- a/core/webpack.js +++ b/core/webpack.js @@ -31,7 +31,6 @@ module.exports = [ }, { entry: { - share_backend: path.resolve(__dirname, 'js/merged-share-backend.js'), systemtags: path.resolve(__dirname, 'js/systemtags/merged-systemtags.js') }, output: { diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 86101707dbf612fd15dffd0e74ccc7bddce54c34..64d59334aad83b2d1d023e6b05f72beeb734a05f 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -84,9 +84,6 @@ class Share extends Constants { 'collectionOf' => $collectionOf, 'supportedFileExtensions' => $supportedFileExtensions ); - if(count(self::$backendTypes) === 1) { - Util::addScript('core', 'dist/share_backend'); - } return true; } \OCP\Util::writeLog('OCP\Share',