Browse Source

Cleanup sharing leftovers

Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
pull/17753/head
John Molakvoæ (skjnldsv) 7 years ago
parent
commit
eebcf89091
No known key found for this signature in database GPG Key ID: 60C25B8C072916CF
  1. 4
      apps/files_sharing/js/dist/additionalScripts.js
  2. 2
      apps/files_sharing/js/dist/additionalScripts.js.map
  3. 2
      apps/files_sharing/js/dist/collaboration.js
  4. 2
      apps/files_sharing/js/dist/collaboration.js.map
  5. 2
      apps/files_sharing/js/dist/files_sharing.js
  6. 2
      apps/files_sharing/js/dist/files_sharing.js.map
  7. 46
      apps/files_sharing/js/dist/files_sharing_tab.js
  8. 2
      apps/files_sharing/js/dist/files_sharing_tab.js.map
  9. 2
      apps/files_sharing/src/additionalScripts.js
  10. 81
      apps/files_sharing/src/share.js
  11. 107
      apps/files_sharing/src/sharetabview.js
  12. 293
      apps/files_sharing/src/style/sharetabview.scss
  13. 6
      apps/files_sharing/src/utils/SharedWithMe.js
  14. 3
      build/compile-handlebars-templates.sh
  15. 24
      core/js/dist/share_backend.js
  16. 1
      core/js/dist/share_backend.js.map
  17. 2
      core/js/dist/systemtags.js
  18. 2
      core/js/dist/systemtags.js.map
  19. 9
      core/js/merged-share-backend.js
  20. 399
      core/js/share.js
  21. 40
      core/js/share/sharedialoglinkshareview.handlebars
  22. 121
      core/js/share/sharedialoglinkshareview_popover_menu.handlebars
  23. 20
      core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars
  24. 5
      core/js/share/sharedialogresharerinfoview.handlebars
  25. 32
      core/js/share/sharedialogshareelistview.handlebars
  26. 107
      core/js/share/sharedialogshareelistview_popover_menu.handlebars
  27. 12
      core/js/share/sharedialogview.handlebars
  28. 72
      core/js/shareconfigmodel.js
  29. 954
      core/js/sharedialoglinkshareview.js
  30. 159
      core/js/sharedialogresharerinfoview.js
  31. 777
      core/js/sharedialogshareelistview.js
  32. 1137
      core/js/sharedialogview.js
  33. 945
      core/js/shareitemmodel.js
  34. 54
      core/js/sharesocialmanager.js
  35. 686
      core/js/sharetemplates.js
  36. 1
      core/webpack.js
  37. 3
      lib/private/Share/Share.php

4
apps/files_sharing/js/dist/additionalScripts.js
File diff suppressed because it is too large
View File

2
apps/files_sharing/js/dist/additionalScripts.js.map
File diff suppressed because it is too large
View File

2
apps/files_sharing/js/dist/collaboration.js

@ -1,2 +1,2 @@
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/js/",t(t.s=67)}({67:function(e,n,r){r.p=OC.linkTo("files_sharing","js/dist/"),r.nc=btoa(OC.requestToken),window.OCP.Collaboration.registerType("file",{action:function(){return new Promise((function(e,n){OC.dialogs.filepicker(t("files_sharing","Link to a file"),(function(t){OC.Files.getClient().getFileInfo(t).then((function(n,t){e(t.id)})).fail((function(){n(new Error("Cannot get fileinfo"))}))}),!1,null,!1,OC.dialogs.FILEPICKER_TYPE_CHOOSE,"",{allowDirectoryChooser:!0})}))},typeString:t("files_sharing","Link to a file"),typeIconClass:"icon-files-dark"})}});
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/js/",t(t.s=65)}({65:function(e,n,r){r.p=OC.linkTo("files_sharing","js/dist/"),r.nc=btoa(OC.requestToken),window.OCP.Collaboration.registerType("file",{action:function(){return new Promise((function(e,n){OC.dialogs.filepicker(t("files_sharing","Link to a file"),(function(t){OC.Files.getClient().getFileInfo(t).then((function(n,t){e(t.id)})).fail((function(){n(new Error("Cannot get fileinfo"))}))}),!1,null,!1,OC.dialogs.FILEPICKER_TYPE_CHOOSE,"",{allowDirectoryChooser:!0})}))},typeString:t("files_sharing","Link to a file"),typeIconClass:"icon-files-dark"})}});
//# sourceMappingURL=collaboration.js.map

2
apps/files_sharing/js/dist/collaboration.js.map
File diff suppressed because it is too large
View File

2
apps/files_sharing/js/dist/files_sharing.js
File diff suppressed because it is too large
View File

2
apps/files_sharing/js/dist/files_sharing.js.map
File diff suppressed because it is too large
View File

46
apps/files_sharing/js/dist/files_sharing_tab.js
File diff suppressed because it is too large
View File

2
apps/files_sharing/js/dist/files_sharing_tab.js.map
File diff suppressed because it is too large
View File

2
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'

81
apps/files_sharing/src/share.js

@ -247,15 +247,94 @@
* @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 = 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}

107
apps/files_sharing/src/sharetabview.js

@ -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
})()

293
apps/files_sharing/src/style/sharetabview.scss

@ -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;
}

6
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',

3
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

24
core/js/dist/share_backend.js
File diff suppressed because it is too large
View File

1
core/js/dist/share_backend.js.map
File diff suppressed because it is too large
View File

2
core/js/dist/systemtags.js
File diff suppressed because it is too large
View File

2
core/js/dist/systemtags.js.map
File diff suppressed because it is too large
View File

9
core/js/merged-share-backend.js

@ -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'

399
core/js/share.js

@ -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()
}
})
})

40
core/js/share/sharedialoglinkshareview.handlebars

@ -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}}

121
core/js/share/sharedialoglinkshareview_popover_menu.handlebars

@ -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>

20
core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars

@ -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>

5
core/js/share/sharedialogresharerinfoview.handlebars

@ -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}}

32
core/js/share/sharedialogshareelistview.handlebars

@ -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>

107
core/js/share/sharedialogshareelistview_popover_menu.handlebars

@ -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>

12
core/js/share/sharedialogview.handlebars

@ -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>

72
core/js/shareconfigmodel.js

@ -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
})()

954
core/js/sharedialoglinkshareview.js

@ -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
})()

159
core/js/sharedialogresharerinfoview.js

@ -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
})()

777
core/js/sharedialogshareelistview.js

@ -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
})()

1137
core/js/sharedialogview.js
File diff suppressed because it is too large
View File

945
core/js/shareitemmodel.js

@ -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
})()

54
core/js/sharesocialmanager.js

@ -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()
})()

686
core/js/sharetemplates.js

@ -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});
})();

1
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: {

3
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',

Loading…
Cancel
Save