aboutsummaryrefslogtreecommitdiffstats
path: root/core/js
diff options
context:
space:
mode:
authorTomasz Grobelny <tomasz@grobelny.net>2018-11-03 23:55:06 +0000
committerTomasz Grobelny <tomasz@grobelny.net>2018-11-04 09:39:19 +0000
commit1fa6e0be23f0684ce76de3311c52e01495a4de7e (patch)
treeef50b564c793d77ef5ade04349f6c5f97a22c7f5 /core/js
parent41687ef00fa5667467564770a4e29403e32d167f (diff)
parentb9783993da7c689b0b1e55dc5696b0c3f90a4c10 (diff)
downloadnextcloud-server-1fa6e0be23f0684ce76de3311c52e01495a4de7e.tar.gz
nextcloud-server-1fa6e0be23f0684ce76de3311c52e01495a4de7e.zip
Merge remote-tracking branch 'upstream/master' into fix_file_move
Signed-off-by: Tomasz Grobelny <tomasz@grobelny.net>
Diffstat (limited to 'core/js')
-rw-r--r--core/js/js.js9
-rw-r--r--core/js/share/sharedialoglinkshareview.handlebars42
-rw-r--r--core/js/share/sharedialoglinkshareview_popover_menu.handlebars68
-rw-r--r--core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars24
-rw-r--r--core/js/share/sharedialogshareelistview.handlebars4
-rw-r--r--core/js/share/sharedialogshareelistview_popover_menu.handlebars23
-rw-r--r--core/js/sharedialoglinkshareview.js589
-rw-r--r--core/js/sharedialogshareelistview.js13
-rw-r--r--core/js/sharedialogview.js110
-rw-r--r--core/js/shareitemmodel.js71
-rw-r--r--core/js/sharetemplates.js227
-rw-r--r--core/js/tests/specHelper.js2
-rw-r--r--core/js/tests/specs/coreSpec.js4
-rw-r--r--core/js/tests/specs/sharedialoglinkshareview.js229
-rw-r--r--core/js/tests/specs/sharedialogshareelistview.js33
-rw-r--r--core/js/tests/specs/sharedialogviewSpec.js49
-rw-r--r--core/js/tests/specs/shareitemmodelSpec.js65
17 files changed, 1162 insertions, 400 deletions
diff --git a/core/js/js.js b/core/js/js.js
index fd6e0a68da5..026cc6bb0d6 100644
--- a/core/js/js.js
+++ b/core/js/js.js
@@ -1562,13 +1562,14 @@ function initCore() {
var resizeMenu = function() {
var appList = $('#appmenu li');
- var headerWidth = $('.header-left').outerWidth() - $('#nextcloud').outerWidth();
+ var rightHeaderWidth = $('.header-right').outerWidth();
+ var headerWidth = $('header').outerWidth();
var usePercentualAppMenuLimit = 0.33;
var minAppsDesktop = 8;
- var availableWidth = headerWidth - $(appList).width();
+ var availableWidth = headerWidth - $('#nextcloud').outerWidth() - (rightHeaderWidth > 210 ? rightHeaderWidth : 210)
var isMobile = $(window).width() < 768;
if (!isMobile) {
- availableWidth = headerWidth * usePercentualAppMenuLimit;
+ availableWidth = availableWidth * usePercentualAppMenuLimit;
}
var appCount = Math.floor((availableWidth / $(appList).width()));
if (isMobile && appCount > minAppsDesktop) {
@@ -1613,7 +1614,7 @@ function initCore() {
}
};
$(window).resize(resizeMenu);
- resizeMenu();
+ setTimeout(resizeMenu, 0);
// just add snapper for logged in users
if($('#app-navigation').length && !$('html').hasClass('lte9')) {
diff --git a/core/js/share/sharedialoglinkshareview.handlebars b/core/js/share/sharedialoglinkshareview.handlebars
index bc7051683a2..64f52704290 100644
--- a/core/js/share/sharedialoglinkshareview.handlebars
+++ b/core/js/share/sharedialoglinkshareview.handlebars
@@ -1,25 +1,39 @@
{{#if shareAllowed}}
-<ul id="shareLink" class="shareWithList">
- <li data-share-id="{{cid}}">
- <div class="avatar icon-public-white"></div><span class="username" title="{{linkShareLabel}}">{{linkShareLabel}}</span>
- <span class="sharingOptionsGroup">
- <span class="shareOption">
- <span class="icon-loading-small hidden"></span>
- <input id="linkCheckbox-{{cid}}" {{#if isLinkShare}}checked="checked"{{/if}} type="checkbox" name="linkCheckbox" class="linkCheckbox permissions checkbox">
- <label for="linkCheckbox-{{cid}}">{{linkShareEnableLabel}}</label>
+<ul class="shareWithList">
+ {{#if nolinkShares}}
+ <li data-share-id="new-share">
+ <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>
- {{#if showMenu}}
- <div class="share-menu" tabindex="0"><span class="icon icon-more"></span>
+ </li>
+ {{/if}}
+ {{#each linkShares}}
+ <li data-share-id="{{cid}}">
+ <div class="avatar icon-public-white"></div><span class="username" title="{{linkShareLabel}}">{{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>
- {{/if}}
- </span>
- </li>
+ </span>
+ </li>
+ {{/each}}
</ul>
{{else}}
-{{#if noSharingPlaceholder}}<input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{noSharingPlaceholder}}" disabled="disabled"/>{{/if}}
+{{#if noSharingPlaceholder}}<input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{noSharingPlaceholder}}" disabled="disabled" />{{/if}}
{{/if}}
diff --git a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars
index 412ed8efca0..59312bc70b0 100644
--- a/core/js/share/sharedialoglinkshareview_popover_menu.handlebars
+++ b/core/js/share/sharedialoglinkshareview_popover_menu.handlebars
@@ -1,11 +1,5 @@
<div class="popovermenu menu">
<ul>
- <li>
- <a href="#" class="menuitem clipboardButton" data-clipboard-text="{{shareLinkURL}}">
- <span class="icon icon-clippy" ></span>
- <span>{{copyLabel}}</span>
- </a>
- </li>
<li class="hidden linkTextMenu">
<span class="menuitem icon-link-text">
<input id="linkText-{{cid}}" class="linkText" type="text" readonly="readonly" value="{{shareLinkURL}}" />
@@ -13,20 +7,21 @@
</li>
{{#if publicUpload}}
<li>
- <span class="shareOption menuitem">
+ <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="shareOption menuitem">
+ <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>
+ </span>
+ </li>
<li>
- <span class="shareOption menuitem">
+ <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>
@@ -35,39 +30,62 @@
{{/if}}
{{#if publicEditing}}
<li id="allowPublicEditingWrapper">
- <span class="shareOption menuitem">
+ <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}}
+ {{#if showHideDownloadCheckbox}}
+ <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>
+ {{/if}}
{{#if showPasswordCheckBox}}
<li>
- <span class="shareOption menuitem">
+ <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="shareOption menuitem icon-share-pass">
+ <span class="menuitem icon-share-pass">
<input id="linkPassText-{{cid}}" class="linkPassText" type="password" placeholder="{{passwordPlaceholder}}" autocomplete="new-password" />
<span class="icon icon-loading-small hidden"></span>
</span>
</li>
{{/if}}
+ {{#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="shareOption menuitem">
+ <span class="menuitem">
<input id="expireDate-{{cid}}" type="checkbox" name="expirationDate" class="expireDate checkbox"
- {{#if hasExpireDate}}checked="checked"{{/if}} {{#if isExpirationEnforced}}disabled="disabled"{{/if}}" />
+ {{#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>
- <input id="expirationDatePicker-{{cid}}" class="datepicker" type="text" placeholder="{{expirationDatePlaceholder}}" value="{{#if hasExpireDate}}{{expireDate}}{{else}}{{defaultExpireDate}}{{/if}}" />
+ <!-- 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>
@@ -75,22 +93,32 @@
<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">
+ <input type="button" class="share-note-delete icon-delete {{#unless hasNote}}hidden{{/unless}}">
</a>
</li>
- <li class="share-note-form share-note-link hidden">
+ <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>
+ </span>
</li>
{{#each social}}
<li>
- <a href="#" class="shareOption menuitem pop-up" data-url="{{url}}" data-window="{{newWindow}}">
+ <a href="#" class="menuitem pop-up" data-url="{{url}}" data-window="{{newWindow}}">
<span class="icon {{iconClass}}"></span>
<span>{{label}}</span>
</a>
</li>
{{/each}}
+ <li>
+ <a href="#" class="unshare"><span class="icon-loading-small hidden"></span><span class="icon icon-delete"></span><span>{{unshareLinkLabel}}</span></a>
+ </li>
+ <li>
+ <a href="#" class="new-share">
+ <span class="icon-loading-small hidden"></span>
+ <span class="icon icon-add"></span>
+ <span>{{newShareLabel}}</span>
+ </a>
+ </li>
</ul>
</div>
diff --git a/core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars b/core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars
index e39c082315b..787f50c6c1e 100644
--- a/core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars
+++ b/core/js/share/sharedialoglinkshareview_popover_menu_pending.handlebars
@@ -1,14 +1,20 @@
-<div class="popovermenu pendingpopover menu">
+<div class="popovermenu open menu">
<ul>
{{#if isPasswordEnforced}}
- <li><span class="shareOption menuitem">
- <input type="checkbox" name="showPassword" id="showPassword-{{cid}}" checked="checked" disabled class="checkbox showPasswordCheckbox" value="1" />
- <label for="showPassword-{{cid}}">{{enablePasswordLabel}}</label>
- </span></li>
- <li class="linkPassMenu"><span class="shareOption menuitem icon-share-pass">
- <input id="linkPassText-{{cid}}" class="linkPassText" type="password" placeholder="{{passwordPlaceholder}}" autocomplete="new-password" />
- <span class="icon icon-loading-small hidden"></span>
- </span></li>
+ <li>
+ <span class="menuitem icon-info">
+ <p>{{enforcedPasswordLabel}}</p>
+ </span>
+ </li>
+ <li class="linkPassMenu">
+ <span class="menuitem">
+ <form autocomplete="off" class="enforcedPassForm">
+ <input id="enforcedPassText" required class="enforcedPassText" type="password"
+ placeholder="{{passwordPlaceholder}}" autocomplete="enforcedPassText" minlength="{{minPasswordLength}}" />
+ <input type="submit" value=" " class="primary icon-checkmark-white">
+ </form>
+ </span>
+ </li>
{{/if}}
</ul>
</div>
diff --git a/core/js/share/sharedialogshareelistview.handlebars b/core/js/share/sharedialogshareelistview.handlebars
index a95949c8157..92c07f80290 100644
--- a/core/js/share/sharedialogshareelistview.handlebars
+++ b/core/js/share/sharedialogshareelistview.handlebars
@@ -5,7 +5,7 @@
<span class="username" title="{{shareWithTitle}}">{{shareWithDisplayName}}</span>
<span class="sharingOptionsGroup">
{{#if editPermissionPossible}}
- <span class="shareOption">
+ <span>
<input id="canEdit-{{cid}}-{{shareId}}" type="checkbox" name="edit" class="permissions checkbox" />
<label for="canEdit-{{cid}}-{{shareId}}">{{canEditLabel}}</label>
</span>
@@ -15,7 +15,7 @@
</div>
</span>
</li>
- {{/each}}
+ {{/each}}
{{#each linkReshares}}
<li data-share-id="{{shareId}}" data-share-type="{{shareType}}">
<div class="avatar" data-username="{{shareInitiator}}"></div>
diff --git a/core/js/share/sharedialogshareelistview_popover_menu.handlebars b/core/js/share/sharedialogshareelistview_popover_menu.handlebars
index c135d31b081..64fe51a3d24 100644
--- a/core/js/share/sharedialogshareelistview_popover_menu.handlebars
+++ b/core/js/share/sharedialogshareelistview_popover_menu.handlebars
@@ -2,7 +2,7 @@
<ul>
{{#if isResharingAllowed}} {{#if sharePermissionPossible}} {{#unless isMailShare}}
<li>
- <span class="shareOption menuitem">
+ <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>
@@ -11,7 +11,7 @@
{{#if isFolder}}
{{#if createPermissionPossible}}{{#unless isMailShare}}
<li>
- <span class="shareOption menuitem">
+ <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>
@@ -19,7 +19,7 @@
{{/unless}}{{/if}}
{{#if updatePermissionPossible}}{{#unless isMailShare}}
<li>
- <span class="shareOption menuitem">
+ <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>
@@ -27,7 +27,7 @@
{{/unless}}{{/if}}
{{#if deletePermissionPossible}}{{#unless isMailShare}}
<li>
- <span class="shareOption menuitem">
+ <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>
@@ -37,14 +37,14 @@
{{#if isMailShare}}
{{#if hasCreatePermission}}
<li>
- <span class="shareOption menuitem">
+ <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="shareOption menuitem">
+ <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>
@@ -58,7 +58,7 @@
</li>
{{#if isTalkEnabled}}
<li>
- <span class="shareOption menuitem">
+ <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>
@@ -73,7 +73,7 @@
{{/if}}
{{/if}}
<li>
- <span class="shareOption menuitem">
+ <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>
@@ -86,13 +86,14 @@
</li>
{{#if isNoteAvailable}}
<li>
- <a href="#" class="share-add"><span class="icon-loading-small hidden"></span>
+ <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">
+ <input type="button" class="share-note-delete icon-delete {{#unless hasNote}}hidden{{/unless}}">
</a>
</li>
- <li class="share-note-form hidden">
+ <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}}" />
diff --git a/core/js/sharedialoglinkshareview.js b/core/js/sharedialoglinkshareview.js
index aac4843c8e0..e5af4ad1f17 100644
--- a/core/js/sharedialoglinkshareview.js
+++ b/core/js/sharedialoglinkshareview.js
@@ -42,15 +42,19 @@
/** @type {boolean} **/
showPending: false,
+ /** @type {string} **/
+ password: '',
+
events: {
- // enable/disable
- 'change .linkCheckbox': 'onLinkCheckBoxChange',
// open menu
'click .share-menu .icon-more': 'onToggleMenu',
+ // hide download
+ 'change .hideDownloadCheckbox': 'onHideDownloadChange',
// password
'focusout input.linkPassText': 'onPasswordEntered',
'keyup input.linkPassText': 'onPasswordKeyUp',
'change .showPasswordCheckbox': 'onShowPasswordClick',
+ 'change .passwordByTalkCheckbox': 'onPasswordByTalkChange',
'change .publicEditingCheckbox': 'onAllowPublicEditingChange',
// copy link url
'click .linkText': 'onLinkTextClick',
@@ -65,7 +69,13 @@
// note
'click .share-add': 'showNoteForm',
'click .share-note-delete': 'deleteNote',
- 'click .share-note-submit': 'updateNote'
+ 'click .share-note-submit': 'updateNote',
+ // remove
+ 'click .unshare': 'onUnshare',
+ // new share
+ 'click .new-share': 'newShare',
+ // enforced pass set
+ 'submit .enforcedPassForm': 'enforcedPasswordSet',
},
initialize: function(options) {
@@ -87,8 +97,35 @@
view.render();
});
- this.model.on('change:linkShare', 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)) {
@@ -97,26 +134,33 @@
throw 'missing OC.Share.ShareConfigModel';
}
- var clipboard = new Clipboard('.clipboardButton');
+ var clipboard = new Clipboard('.clipboard-button');
clipboard.on('success', function(e) {
- var $menu = $(e.trigger);
- var $linkTextMenu = $menu.parent().next('li.linkTextMenu')
+ var $trigger = $(e.trigger);
- $menu.tooltip('hide')
+ $trigger.tooltip('hide')
.attr('data-original-title', t('core', 'Copied!'))
.tooltip('fixTitle')
.tooltip({placement: 'bottom', trigger: 'manual'})
.tooltip('show');
_.delay(function() {
- $menu.tooltip('hide');
- $menu.tooltip('destroy');
+ $trigger.tooltip('hide')
+ .attr('data-original-title', t('core', 'Copy link'))
+ .tooltip('fixTitle')
}, 3000);
});
clipboard.on('error', function (e) {
- var $menu = $(e.trigger);
- var $linkTextMenu = $menu.parent().next('li.linkTextMenu');
+ 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!');
@@ -141,75 +185,161 @@
});
},
- onLinkCheckBoxChange: function() {
- var $checkBox = this.$el.find('.linkCheckbox');
- var $loading = $checkBox.siblings('.icon-loading-small');
- if(!$loading.hasClass('hidden')) {
+ 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;
}
- if($checkBox.is(':checked')) {
- if(this.configModel.get('enforcePasswordForPublicLink') === false) {
- $loading.removeClass('hidden');
- // this will create it
- this.model.saveLinkShare();
- $('.share-menu .icon-more').click();
- $('.share-menu .icon-more + .popovermenu .clipboardButton').click();
- } else {
- // force the rendering of the menu
- this.showPending = true;
- this.render()
- $('.share-menu .icon-more').click();
- $('.share-menu .icon-more + .popovermenu input:eq(1)').focus()
- }
+ // 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;
+ this.render();
+ $li.find('#enforcedPassText').focus();
} else {
- if (this.model.get('linkShare').isLinkShare) {
- $loading.removeClass('hidden');
- this.model.removeLinkShare();
- } else {
- this.showPending = false;
- this.render()
- }
+ // 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+'"]');
+ // only open the menu by default if this is the first share
+ if ($newShare && shares.length === 1) {
+ $menu = $newShare.find('.popovermenu');
+ OC.showMenu(null, $menu);
+ }
+ }
+ },
+ error: function() {
+ 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
+ });
}
},
- onLinkTextClick: function() {
- var $el = this.$el.find('.linkText');
+ 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();
},
- onShowPasswordClick: function() {
- this.$el.find('.linkPass').slideToggle(OC.menuSpeed);
- this.$el.find('.linkPassMenu').toggleClass('hidden');
- if(!this.$el.find('.showPasswordCheckbox').is(':checked')) {
+ 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: ''
+ password: '',
+ cid: shareId
});
} else {
if (!OC.Util.isIE()) {
- this.$el.find('.linkPassText').focus();
+ $li.find('.linkPassText').focus();
}
}
},
onPasswordKeyUp: function(event) {
if(event.keyCode === 13) {
- this.onPasswordEntered();
+ this.onPasswordEntered(event);
}
},
- onPasswordEntered: function() {
- var $loading = this.$el.find('.linkPassMenu .icon-loading-small');
+ 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 = this.$el.find('.linkPassText');
+ var $input = $li.find('.linkPassText');
$input.removeClass('error');
var password = $input.val();
- if (this.$el.find('.linkPassText').attr('placeholder') === PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL) {
+ 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) {
@@ -228,7 +358,8 @@
.addClass('inlineblock');
this.model.saveLinkShare({
- password: password
+ password: password,
+ cid: shareId
}, {
complete: function(model) {
$loading.removeClass('inlineblock').addClass('hidden');
@@ -244,8 +375,37 @@
});
},
- onAllowPublicEditingChange: function() {
- var $checkbox = this.$('.publicEditingCheckbox');
+ 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;
@@ -254,15 +414,28 @@
}
this.model.saveLinkShare({
- permissions: permissions
+ 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(e) {
- var permissions = e.currentTarget.value;
+ 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
+ permissions: permissions,
+ cid: shareId
});
},
@@ -276,7 +449,7 @@
var $form = $menu.next('li.share-note-form');
// show elements
- $menu.find('.share-note-delete').toggle();
+ $menu.find('.share-note-delete').toggleClass('hidden');
$form.toggleClass('hidden');
$form.find('textarea').focus();
},
@@ -294,7 +467,7 @@
$form.find('.share-note').val('');
$form.addClass('hidden');
- $menu.find('.share-note-delete').hide();
+ $menu.find('.share-note-delete').addClass('hidden');
self.sendNote('', shareId, $menu);
},
@@ -349,6 +522,11 @@
},
render: function() {
+ this.$el.find('.has-tooltip').tooltip();
+
+ // reset previously set passwords
+ this.password = '';
+
var linkShareTemplate = this.template();
var resharingAllowed = this.model.sharePermissionPossible();
@@ -370,43 +548,21 @@
&& this.model.createPermissionPossible()
&& this.configModel.isPublicUploadEnabled();
- var publicUploadRWChecked = '';
- var publicUploadRChecked = '';
- var publicUploadWChecked = '';
-
- switch (this.model.linkSharePermissions()) {
- 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 publicEditingChecked = '';
if(this.model.isPublicEditingAllowed()) {
publicEditingChecked = 'checked="checked"';
}
- var isLinkShare = this.model.get('linkShare').isLinkShare;
- var isPasswordSet = !!this.model.get('linkShare').password;
var isPasswordEnforced = this.configModel.get('enforcePasswordForPublicLink');
var isPasswordEnabledByDefault = this.configModel.get('enableLinkPasswordByDefault') === true;
- var showPasswordCheckBox = isLinkShare
- && ( !this.configModel.get('enforcePasswordForPublicLink')
- || !this.model.get('linkShare').password);
var passwordPlaceholderInitial = this.configModel.get('enforcePasswordForPublicLink')
? PASSWORD_PLACEHOLDER_MESSAGE : PASSWORD_PLACEHOLDER_MESSAGE_OPTIONAL;
var publicEditable =
!this.model.isFolder()
- && isLinkShare
&& this.model.updatePermissionPossible();
- var link = this.model.get('linkShare').link;
var social = [];
OC.Share.Social.Collection.each(function(model) {
var url = model.get('url');
@@ -420,57 +576,33 @@
newWindow: model.get('newWindow')
});
});
-
- var defaultExpireDays = this.configModel.get('defaultExpireDate');
var isExpirationEnforced = this.configModel.get('isDefaultExpireDateEnforced');
- var hasExpireDate = !!this.model.get('linkShare').expiration || isExpirationEnforced;
-
- var expireDate;
- if (hasExpireDate) {
- expireDate = moment(this.model.get('linkShare').expiration, 'YYYY-MM-DD').format('DD-MM-YYYY');
- }
// what if there is another date picker on that page?
var minDate = new Date();
- var maxDate = null;
// min date should always be the next day
minDate.setDate(minDate.getDate()+1);
- if(hasExpireDate) {
- if(isExpirationEnforced) {
- // TODO: hack: backend returns string instead of integer
- var shareTime = this.model.get('linkShare').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);
- }
- }
$.datepicker.setDefaults({
- minDate: minDate,
- maxDate: maxDate
+ minDate: minDate
});
this.$el.find('.datepicker').datepicker({dateFormat : 'dd-mm-yy'});
- var popover = this.popoverMenuTemplate({
- cid: this.model.get('linkShare').id,
- copyLabel: t('core', 'Copy link'),
- social: social,
+ var minPasswordLength = 4
+ // password policy?
+ if(oc_capabilities.password_policy && oc_capabilities.password_policy.minLength) {
+ minPasswordLength = oc_capabilities.password_policy.minLength;
+ }
- shareLinkURL: this.model.get('linkShare').link,
+ var popoverBase = {
+ social: social,
urlLabel: t('core', 'Link'),
- enablePasswordLabel: t('core', 'Password protect'),
+ hideDownloadLabel: t('core', 'Hide download'),
+ enablePasswordLabel: isPasswordEnforced ? t('core', 'Password protection enforced') : t('core', 'Password protect'),
passwordLabel: t('core', 'Password'),
- passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
passwordPlaceholderInitial: passwordPlaceholderInitial,
- isPasswordSet: isPasswordSet || isPasswordEnabledByDefault || isPasswordEnforced,
- showPasswordCheckBox: showPasswordCheckBox,
- publicUpload: publicUpload && isLinkShare,
+ publicUpload: publicUpload,
publicEditing: publicEditable,
publicEditingChecked: publicEditingChecked,
publicEditingLabel: t('core', 'Allow editing'),
@@ -482,41 +614,43 @@
publicUploadRWValue: OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE,
publicUploadRValue: OC.PERMISSION_READ,
publicUploadWValue: OC.PERMISSION_CREATE,
- publicUploadRWChecked: publicUploadRWChecked,
- publicUploadRChecked: publicUploadRChecked,
- publicUploadWChecked: publicUploadWChecked,
- expireDateLabel: t('core', 'Set expiration date'),
+ expireDateLabel: isExpirationEnforced ? t('core', 'Expiration date enforced') : t('core', 'Set expiration date'),
expirationLabel: t('core', 'Expiration'),
expirationDatePlaceholder: t('core', 'Expiration date'),
- hasExpireDate: hasExpireDate,
isExpirationEnforced: isExpirationEnforced,
isPasswordEnforced: isPasswordEnforced,
- expireDate: expireDate,
defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today
- shareNote: this.model.get('linkShare').note,
addNoteLabel: t('core', 'Note to recipient'),
- });
+ unshareLabel: t('core', 'Unshare'),
+ unshareLinkLabel: t('core', 'Delete share link'),
+ newShareLabel: t('core', 'Add another link'),
+ };
- var pendingPopover = this.pendingPopoverMenuTemplate({
- cid: this.model.get('linkShare').id,
- enablePasswordLabel: t('core', 'Password protect'),
- passwordLabel: t('core', 'Password'),
- passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
- passwordPlaceholderInitial: passwordPlaceholderInitial,
- showPasswordCheckBox: showPasswordCheckBox,
+ 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 popover = this.getPopoverObject(linkShares[i])
+ linkShares[i].popoverMenu = this.popoverMenuTemplate(_.extend({}, popoverBase, popover));
+ linkShares[i].pendingPopoverMenu = pendingPopoverMenu
+ }
+ }
this.$el.html(linkShareTemplate({
- cid: this.model.get('linkShare').id,
+ linkShares: linkShares,
shareAllowed: true,
- isLinkShare: isLinkShare,
- linkShareLabel: t('core', 'Share link'),
- linkShareEnableLabel: t('core', 'Enable'),
- popoverMenu: popover,
- pendingPopoverMenu: pendingPopover,
- showMenu: isLinkShare || this.showPending,
- showPending: this.showPending && !isLinkShare
+ nolinkShares: linkShares.length === 0,
+ newShareLabel: t('core', 'Share link'),
+ newShareTitle: t('core', 'New share link'),
+ pendingPopoverMenu: pendingPopoverMenu,
+ showPending: this.showPending === 'new',
}));
this.delegateEvents();
@@ -533,9 +667,17 @@
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);
- this._menuOpen = $li.data('share-id');
+
+ // 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();
+ }
},
/**
@@ -613,24 +755,179 @@
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);
- }
+ self.setExpirationDate(expireDate, shareId);
+ },
+ maxDate: maxDate
});
$(expirationDatePicker).datepicker('show');
$(expirationDatePicker).focus();
},
- setExpirationDate: function(expireDate) {
- this.model.saveLinkShare({expireDate: expireDate});
+ setExpirationDate: function(expireDate, shareId) {
+ this.model.saveLinkShare({expireDate: expireDate, cid: shareId});
},
+ /**
+ * 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,
+ })
+ },
+
+ 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 showPasswordCheckBox = !isPasswordEnforced || !share.password;
+ 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 showHideDownloadCheckbox = !this.model.isFolder();
+ 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,
+ showPasswordCheckBox: showPasswordCheckBox,
+ 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,
+ showHideDownloadCheckbox: showHideDownloadCheckbox,
+ hideDownload: hideDownload,
+ isExpirationEnforced: isExpirationEnforced,
+ }
+ },
+
+ onUnshare: function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ var self = this;
+ var $element = $(event.target);
+ if (!$element.is('a')) {
+ $element = $element.closest('a');
+ }
+
+ var $loading = $element.find('.icon-loading-small').eq(0);
+ if(!$loading.hasClass('hidden')) {
+ // in process
+ return false;
+ }
+ $loading.removeClass('hidden');
+
+ var $li = $element.closest('li[data-share-id]');
+
+ var shareId = $li.data('share-id');
+
+ self.model.removeShare(shareId, {
+ success: function() {
+ $li.remove();
+ self.render()
+ },
+ error: function() {
+ $loading.addClass('hidden');
+ OC.Notification.showTemporary(t('core', 'Could not unshare'));
+ }
+ });
+ return false;
+ },
+
+
});
OC.Share.ShareDialogLinkShareView = ShareDialogLinkShareView;
diff --git a/core/js/sharedialogshareelistview.js b/core/js/sharedialogshareelistview.js
index 93373a54435..8b709f0d74d 100644
--- a/core/js/sharedialogshareelistview.js
+++ b/core/js/sharedialogshareelistview.js
@@ -134,6 +134,8 @@
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),
@@ -159,7 +161,8 @@
isTalkEnabled: oc_appswebroots['spreed'] !== undefined,
secureDropMode: !this.model.hasReadPermission(shareIndex),
hasExpireDate: this.model.getExpireDate(shareIndex) !== null,
- shareNote: this.model.getNote(shareIndex),
+ 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
@@ -314,7 +317,9 @@
var $edit = _this.$('#canEdit-' + _this.cid + '-' + sharee.shareId);
if($edit.length === 1) {
$edit.prop('checked', sharee.editPermissionState === 'checked');
- $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate');
+ if (sharee.isFolder) {
+ $edit.prop('indeterminate', sharee.editPermissionState === 'indeterminate');
+ }
}
});
this.$('.popovermenu').on('afterHide', function() {
@@ -384,7 +389,7 @@
var $form = $menu.next('li.share-note-form');
// show elements
- $menu.find('.share-note-delete').toggle();
+ $menu.find('.share-note-delete').toggleClass('hidden');
$form.toggleClass('hidden');
$form.find('textarea').focus();
},
@@ -403,7 +408,7 @@
$form.find('.share-note').val('');
$form.addClass('hidden');
- $menu.find('.share-note-delete').hide();
+ $menu.find('.share-note-delete').addClass('hidden');
self.sendNote('', shareId, $menu);
},
diff --git a/core/js/sharedialogview.js b/core/js/sharedialogview.js
index 9c648357e61..082bf9571d7 100644
--- a/core/js/sharedialogview.js
+++ b/core/js/sharedialogview.js
@@ -312,6 +312,41 @@
var suggestions = exactMatches.concat(users).concat(groups).concat(remotes).concat(remoteGroups).concat(emails).concat(circles).concat(rooms).concat(lookup);
+ function dynamicSort(property) {
+ return function (a,b) {
+ var aProperty = '';
+ var bProperty = '';
+ if (typeof a[property] !== 'undefined') {
+ aProperty = a[property];
+ }
+ if (typeof b[property] !== 'undefined') {
+ bProperty = b[property];
+ }
+ return (aProperty < bProperty) ? -1 : (aProperty > bProperty) ? 1 : 0;
+ }
+ }
+
+ /**
+ * Sort share entries by uuid to properly group them
+ */
+ var grouped = suggestions.sort(dynamicSort('uuid'));
+
+ var previousUuid = null;
+ var groupedLength = grouped.length;
+ var result = [];
+ /**
+ * build the result array that only contains all contact entries from
+ * merged contacts, if the search term matches its contact name
+ */
+ for (i = 0; i < groupedLength; i++) {
+ if (typeof grouped[i].uuid !== 'undefined' && grouped[i].uuid === previousUuid) {
+ grouped[i].merged = true;
+ }
+ if (searchTerm === grouped[i].name || typeof grouped[i].merged === 'undefined') {
+ result.push(grouped[i]);
+ }
+ previousUuid = grouped[i].uuid;
+ }
var moreResultsAvailable =
(
oc_config['sharing.maxAutocompleteResults'] > 0
@@ -328,7 +363,7 @@
)
);
- deferred.resolve(suggestions, exactMatches, moreResultsAvailable);
+ deferred.resolve(result, exactMatches, moreResultsAvailable);
} else {
deferred.reject(result.ocs.meta.message);
}
@@ -441,33 +476,72 @@
},
autocompleteRenderItem: function(ul, item) {
-
+ var icon = 'icon-user';
var text = item.label;
+ if (typeof item.name !== 'undefined') {
+ text = item.name;
+ }
if (item.value.shareType === OC.Share.SHARE_TYPE_GROUP) {
- text = t('core', '{sharee} (group)', { sharee: text }, undefined, { escape: false });
+ icon = 'icon-contacts-dark';
} else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE) {
- text = t('core', '{sharee} (remote)', {sharee: text}, undefined, {escape: false});
+ icon = 'icon-shared';
} else if (item.value.shareType === OC.Share.SHARE_TYPE_REMOTE_GROUP) {
text = t('core', '{sharee} (remote group)', { sharee: text }, undefined, { escape: false });
+ icon = 'icon-shared';
} else if (item.value.shareType === OC.Share.SHARE_TYPE_EMAIL) {
- text = t('core', '{sharee} (email)', { sharee: text }, undefined, { escape: false });
+ icon = 'icon-mail';
} else if (item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) {
text = t('core', '{sharee} ({type}, {owner})', {sharee: text, type: item.value.circleInfo, owner: item.value.circleOwner}, undefined, {escape: false});
+ icon = 'icon-circle';
} else if (item.value.shareType === OC.Share.SHARE_TYPE_ROOM) {
- text = t('core', '{sharee} (conversation)', { sharee: text }, undefined, { escape: false });
+ icon = 'icon-talk';
+ }
+ var description = '';
+ var getTranslatedType = function(type) {
+ switch (type) {
+ case 'HOME':
+ return t('core', 'Home');
+ case 'WORK':
+ return t('core', 'Home');
+ case 'OTHER':
+ return t('core', 'Other');
+ default:
+ return type;
+ }
+ };
+ if (typeof item.type !== 'undefined' && item.type !== null) {
+ description = getTranslatedType(item.type);
}
var insert = $("<div class='share-autocomplete-item'/>");
- var avatar = $("<div class='avatardiv'></div>").appendTo(insert);
- if (item.value.shareType === OC.Share.SHARE_TYPE_USER || item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) {
- avatar.avatar(item.value.shareWith, 32, undefined, undefined, undefined, item.label);
+ if (item.merged) {
+ insert.addClass('merged');
+ text = item.value.shareWith;
} else {
- avatar.imageplaceholder(text, undefined, 32);
+ var avatar = $("<div class='avatardiv'></div>").appendTo(insert);
+ if (item.value.shareType === OC.Share.SHARE_TYPE_USER || item.value.shareType === OC.Share.SHARE_TYPE_CIRCLE) {
+ avatar.avatar(item.value.shareWith, 32, undefined, undefined, undefined, item.label);
+ } else {
+ if (typeof item.uuid === 'undefined') {
+ item.uuid = text;
+ }
+ avatar.imageplaceholder(item.uuid, text, 32);
+ }
+ description = item.value.shareWith;
+ }
+ if (description !== '') {
+ insert.addClass('with-description');
}
$("<div class='autocomplete-item-text'></div>")
- .text(text)
+ .html(
+ text.replace(
+ new RegExp(this.term, "gi"),
+ "<span class='ui-state-highlight'>$&</span>")
+ + '<span class="autocomplete-item-details">' + description + '</span>'
+ )
.appendTo(insert);
insert.attr('title', item.value.shareWith);
+ insert.append('<span class="icon '+icon+'" title="' + text + '"></span>');
insert = $("<a>")
.append(insert);
return $("<li>")
@@ -479,6 +553,20 @@
_onSelectRecipient: function(e, s) {
var self = this;
+ if (e.keyCode == 9) {
+ e.preventDefault();
+ if (typeof s.item.name !== 'undefined') {
+ e.target.value = s.item.name;
+ } else {
+ e.target.value = s.item.label;
+ }
+ setTimeout(function() {
+ $(e.target).attr('disabled', false)
+ .autocomplete('search', $(e.target).val());
+ }, 0);
+ return false;
+ }
+
e.preventDefault();
// Ensure that the keydown handler for the input field is not
// called; otherwise it would try to add the recipient again, which
diff --git a/core/js/shareitemmodel.js b/core/js/shareitemmodel.js
index f4a3caf1370..f4ac03e1c18 100644
--- a/core/js/shareitemmodel.js
+++ b/core/js/shareitemmodel.js
@@ -16,10 +16,10 @@
/**
* @typedef {object} OC.Share.Types.LinkShareInfo
- * @property {bool} isLinkShare
* @property {string} token
+ * @property {bool} hideDownload
* @property {string|null} password
- * @property {string} link
+ * @property {bool} sendPasswordByTalk
* @property {number} permissions
* @property {Date} expiration
* @property {number} stime share time
@@ -99,7 +99,7 @@
defaults: {
allowPublicUploadStatus: false,
permissions: 0,
- linkShare: {}
+ linkShares: []
},
/**
@@ -129,15 +129,20 @@
delete attributes.expiration;
}
- if (this.get('linkShare') && this.get('linkShare').isLinkShare) {
- shareId = this.get('linkShare').id;
+ 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
@@ -149,12 +154,6 @@
return call;
},
- removeLinkShare: function() {
- if (this.get('linkShare')) {
- return this.removeShare(this.get('linkShare').id);
- }
- },
-
addShare: function(attributes, options) {
var shareType = attributes.shareType;
attributes = _.extend({}, attributes);
@@ -314,13 +313,13 @@
},
/**
- * Returns whether this item has a link share
+ * Returns whether this item has link shares
*
* @return {bool} true if a link share exists, false otherwise
*/
- hasLinkShare: function() {
- var linkShare = this.get('linkShare');
- if (linkShare && linkShare.isLinkShare) {
+ hasLinkShares: function() {
+ var linkShares = this.get('linkShares');
+ if (linkShares && linkShares.length > 0) {
return true;
}
return false;
@@ -614,6 +613,12 @@
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 '';
}
@@ -628,12 +633,16 @@
/**
* @returns {int}
*/
- linkSharePermissions: function() {
- if (!this.hasLinkShare()) {
+ linkSharePermissions: function(shareId) {
+ var linkShares = this.get('linkShares');
+ var shareIndex = _.findIndex(linkShares, function(share) {return share.id === shareId})
+
+ if (!this.hasLinkShares()) {
return -1;
- } else {
- return this.get('linkShare').permissions;
+ } else if (linkShares.length > 0 && shareIndex !== -1) {
+ return linkShares[shareIndex].permissions;
}
+ return -1;
},
_getUrl: function(base, params) {
@@ -829,7 +838,7 @@
this._legacyFillCurrentShares(shares);
- var linkShare = { isLinkShare: false };
+ var linkShares = [];
// filter out the share by link
shares = _.reject(shares,
/**
@@ -842,7 +851,7 @@
|| share.item_source === this.get('itemSource'));
if (isShareLink) {
- /*
+ /**
* Ignore reshared link shares for now
* FIXME: Find a way to display properly
*/
@@ -862,17 +871,13 @@
} else {
link += OC.generateUrl('/s/') + share.token;
}
- linkShare = {
- isLinkShare: true,
- id: share.id,
- token: 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,
- link: link,
- permissions: share.permissions,
- // currently expiration is only effective for link shares.
- expiration: share.expiration,
- stime: share.stime
- };
+ sendPasswordByTalk: share.send_password_by_talk
+ }));
return share;
}
@@ -883,7 +888,7 @@
return {
reshare: data.reshare,
shares: shares,
- linkShare: linkShare,
+ linkShares: linkShares,
permissions: permissions,
allowPublicUploadStatus: allowPublicUploadStatus,
allowPublicEditingStatus: allowPublicEditingStatus,
@@ -919,7 +924,7 @@
getShareTypes: function() {
var result;
result = _.pluck(this.getSharesWithCurrentItem(), 'share_type');
- if (this.hasLinkShare()) {
+ if (this.hasLinkShares()) {
result.push(OC.Share.SHARE_TYPE_LINK);
}
return _.uniq(result);
diff --git a/core/js/sharetemplates.js b/core/js/sharetemplates.js
index efdd3ff6606..6469e264d75 100644
--- a/core/js/sharetemplates.js
+++ b/core/js/sharetemplates.js
@@ -1,33 +1,28 @@
(function() {
var template = Handlebars.template, templates = OC.Share.Templates = OC.Share.Templates || {};
templates['sharedialoglinkshareview'] = template({"1":function(container,depth0,helpers,partials,data) {
- var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+ var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {});
- return "<ul id=\"shareLink\" class=\"shareWithList\">\n <li data-share-id=\""
- + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
- + "\">\n <div class=\"avatar icon-public-white\"></div><span class=\"username\" title=\""
- + alias4(((helper = (helper = helpers.linkShareLabel || (depth0 != null ? depth0.linkShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"linkShareLabel","hash":{},"data":data}) : helper)))
- + "\">"
- + alias4(((helper = (helper = helpers.linkShareLabel || (depth0 != null ? depth0.linkShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"linkShareLabel","hash":{},"data":data}) : helper)))
- + "</span>\n <span class=\"sharingOptionsGroup\">\n <span class=\"shareOption\">\n <span class=\"icon-loading-small hidden\"></span>\n <input id=\"linkCheckbox-"
- + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
- + "\" "
- + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isLinkShare : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " type=\"checkbox\" name=\"linkCheckbox\" class=\"linkCheckbox permissions checkbox\">\n <label for=\"linkCheckbox-"
- + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
- + "\">"
- + alias4(((helper = (helper = helpers.linkShareEnableLabel || (depth0 != null ? depth0.linkShareEnableLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"linkShareEnableLabel","hash":{},"data":data}) : helper)))
- + "</label>\n </span>\n"
- + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showMenu : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " </span>\n </li>\n</ul>\n";
+ return "<ul class=\"shareWithList\">\n"
+ + ((stack1 = helpers["if"].call(alias1,(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(alias1,(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) {
- return "checked=\"checked\"";
-},"4":function(container,depth0,helpers,partials,data) {
- var stack1;
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <div class=\"share-menu\" tabindex=\"0\"><span class=\"icon icon-more\"></span>\n"
- + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.program(7, data, 0),"data":data})) != null ? stack1 : "")
- + " </div>\n";
+ return " <li data-share-id=\"new-share\">\n <div class=\"avatar icon-public-white\"></div>\n <span class=\"username\">"
+ + alias4(((helper = (helper = helpers.newShareLabel || (depth0 != null ? depth0.newShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"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(alias1,(depth0 != null ? depth0.showPending : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\" title=\""
+ + alias4(((helper = (helper = helpers.newShareTitle || (depth0 != null ? depth0.newShareTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"newShareTitle","hash":{},"data":data}) : helper)))
+ + "\"></a>\n <span class=\"icon icon-loading-small "
+ + ((stack1 = helpers.unless.call(alias1,(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(alias1,(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;
@@ -35,33 +30,53 @@ templates['sharedialoglinkshareview'] = template({"1":function(container,depth0,
+ ((stack1 = ((helper = (helper = helpers.pendingPopoverMenu || (depth0 != null ? depth0.pendingPopoverMenu : depth0)) != null ? helper : helpers.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=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <li data-share-id=\""
+ + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ + "\">\n <div class=\"avatar icon-public-white\"></div><span class=\"username\" title=\""
+ + alias4(((helper = (helper = helpers.linkShareLabel || (depth0 != null ? depth0.linkShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"linkShareLabel","hash":{},"data":data}) : helper)))
+ + "\">"
+ + alias4(((helper = (helper = helpers.linkShareLabel || (depth0 != null ? depth0.linkShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"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=\""
+ + alias4(((helper = (helper = helpers.shareLinkURL || (depth0 != null ? depth0.shareLinkURL : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareLinkURL","hash":{},"data":data}) : helper)))
+ + "\" title=\""
+ + alias4(((helper = (helper = helpers.copyLabel || (depth0 != null ? depth0.copyLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"copyLabel","hash":{},"data":data}) : helper)))
+ + "\"></a>\n <div class=\"share-menu\">\n <a href=\"#\" class=\"icon icon-more "
+ + ((stack1 = helpers["if"].call(alias1,(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(alias1,(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(alias1,(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;
return " "
+ ((stack1 = ((helper = (helper = helpers.popoverMenu || (depth0 != null ? depth0.popoverMenu : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"popoverMenu","hash":{},"data":data}) : helper))) != null ? stack1 : "")
+ "\n";
-},"9":function(container,depth0,helpers,partials,data) {
+},"10":function(container,depth0,helpers,partials,data) {
var stack1;
- return ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.noSharingPlaceholder : depth0),{"name":"if","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ 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";
-},"10":function(container,depth0,helpers,partials,data) {
+},"11":function(container,depth0,helpers,partials,data) {
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
return "<input id=\"shareWith-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\" class=\"shareWithField\" type=\"text\" placeholder=\""
+ alias4(((helper = (helper = helpers.noSharingPlaceholder || (depth0 != null ? depth0.noSharingPlaceholder : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"noSharingPlaceholder","hash":{},"data":data}) : helper)))
- + "\" disabled=\"disabled\"/>";
+ + "\" disabled=\"disabled\" />";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1;
- 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(9, data, 0),"data":data})) != null ? stack1 : "");
+ 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=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li>\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\""
+ return " <li>\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\""
+ alias4(((helper = (helper = helpers.publicUploadRValue || (depth0 != null ? depth0.publicUploadRValue : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicUploadRValue","hash":{},"data":data}) : helper)))
+ "\" id=\"sharingDialogAllowPublicUpload-r-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
@@ -71,7 +86,7 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.publicUploadRLabel || (depth0 != null ? depth0.publicUploadRLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicUploadRLabel","hash":{},"data":data}) : helper)))
- + "</label>\n </span>\n </li>\n <li>\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\""
+ + "</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=\""
+ alias4(((helper = (helper = helpers.publicUploadRWValue || (depth0 != null ? depth0.publicUploadRWValue : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicUploadRWValue","hash":{},"data":data}) : helper)))
+ "\" id=\"sharingDialogAllowPublicUpload-rw-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
@@ -81,7 +96,7 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.publicUploadRWLabel || (depth0 != null ? depth0.publicUploadRWLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicUploadRWLabel","hash":{},"data":data}) : helper)))
- + "</label>\n </span></li>\n <li>\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"radio\" name=\"publicUpload\" value=\""
+ + "</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=\""
+ alias4(((helper = (helper = helpers.publicUploadWValue || (depth0 != null ? depth0.publicUploadWValue : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicUploadWValue","hash":{},"data":data}) : helper)))
+ "\" id=\"sharingDialogAllowPublicUpload-w-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
@@ -95,7 +110,7 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont
},"3":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li id=\"allowPublicEditingWrapper\">\n <span class=\"shareOption menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"allowPublicEditing\" id=\"sharingDialogAllowPublicEditing-"
+ return " <li id=\"allowPublicEditingWrapper\">\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"allowPublicEditing\" id=\"sharingDialogAllowPublicEditing-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\" class=\"checkbox publicEditingCheckbox\" "
+ ((stack1 = ((helper = (helper = helpers.publicEditingChecked || (depth0 != null ? depth0.publicEditingChecked : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"publicEditingChecked","hash":{},"data":data}) : helper))) != null ? stack1 : "")
@@ -107,41 +122,69 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont
},"5":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li>\n <span class=\"shareOption menuitem\">\n <input type=\"checkbox\" name=\"showPassword\" id=\"showPassword-"
+ return " <li>\n <span class=\"menuitem\">\n <span class=\"icon-loading-small hidden\"></span>\n <input type=\"checkbox\" name=\"hideDownload\" id=\"sharingDialogHideDownload-"
+ + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ + "\" class=\"checkbox hideDownloadCheckbox\"\n "
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hideDownload : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " />\n <label for=\"sharingDialogHideDownload-"
+ + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ + "\">"
+ + alias4(((helper = (helper = helpers.hideDownloadLabel || (depth0 != null ? depth0.hideDownloadLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"hideDownloadLabel","hash":{},"data":data}) : helper)))
+ + "</label>\n </span>\n </li>\n";
+},"6":function(container,depth0,helpers,partials,data) {
+ return "checked=\"checked\"";
+},"8":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <li>\n <span class=\"menuitem\">\n <input type=\"checkbox\" name=\"showPassword\" id=\"showPassword-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\" class=\"checkbox showPasswordCheckbox\"\n "
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " "
- + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordEnforced : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordEnforced : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " value=\"1\" />\n <label for=\"showPassword-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.enablePasswordLabel || (depth0 != null ? depth0.enablePasswordLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"enablePasswordLabel","hash":{},"data":data}) : helper)))
+ "</label>\n </span>\n </li>\n <li class=\""
- + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"unless","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " linkPassMenu\">\n <span class=\"shareOption menuitem icon-share-pass\">\n <input id=\"linkPassText-"
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isPasswordSet : depth0),{"name":"unless","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " linkPassMenu\">\n <span class=\"menuitem icon-share-pass\">\n <input id=\"linkPassText-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\" class=\"linkPassText\" type=\"password\" placeholder=\""
+ alias4(((helper = (helper = helpers.passwordPlaceholder || (depth0 != null ? depth0.passwordPlaceholder : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"passwordPlaceholder","hash":{},"data":data}) : helper)))
+ "\" autocomplete=\"new-password\" />\n <span class=\"icon icon-loading-small hidden\"></span>\n </span>\n </li>\n";
-},"6":function(container,depth0,helpers,partials,data) {
- return "checked=\"checked\"";
-},"8":function(container,depth0,helpers,partials,data) {
+},"9":function(container,depth0,helpers,partials,data) {
return "disabled=\"disabled\"";
-},"10":function(container,depth0,helpers,partials,data) {
+},"11":function(container,depth0,helpers,partials,data) {
return "hidden";
-},"12":function(container,depth0,helpers,partials,data) {
+},"13":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=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-"
+ + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ + "\" class=\"checkbox passwordByTalkCheckbox\"\n "
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isPasswordByTalkSet : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " />\n <label for=\"passwordByTalk-"
+ + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ + "\">"
+ + alias4(((helper = (helper = helpers.passwordByTalkLabel || (depth0 != null ? depth0.passwordByTalkLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"passwordByTalkLabel","hash":{},"data":data}) : helper)))
+ + "</label>\n </span>\n </li>\n";
+},"15":function(container,depth0,helpers,partials,data) {
+ return "datepicker";
+},"17":function(container,depth0,helpers,partials,data) {
var helper;
return container.escapeExpression(((helper = (helper = helpers.expireDate || (depth0 != null ? depth0.expireDate : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"expireDate","hash":{},"data":data}) : helper)));
-},"14":function(container,depth0,helpers,partials,data) {
+},"19":function(container,depth0,helpers,partials,data) {
var helper;
return container.escapeExpression(((helper = (helper = helpers.defaultExpireDate || (depth0 != null ? depth0.defaultExpireDate : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"defaultExpireDate","hash":{},"data":data}) : helper)));
-},"16":function(container,depth0,helpers,partials,data) {
+},"21":function(container,depth0,helpers,partials,data) {
+ return "readonly";
+},"23":function(container,depth0,helpers,partials,data) {
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li>\n <a href=\"#\" class=\"shareOption menuitem pop-up\" data-url=\""
+ return " <li>\n <a href=\"#\" class=\"menuitem pop-up\" data-url=\""
+ alias4(((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"url","hash":{},"data":data}) : helper)))
+ "\" data-window=\""
+ alias4(((helper = (helper = helpers.newWindow || (depth0 != null ? depth0.newWindow : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"newWindow","hash":{},"data":data}) : helper)))
@@ -153,30 +196,28 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return "<div class=\"popovermenu menu\">\n <ul>\n <li>\n <a href=\"#\" class=\"menuitem clipboardButton\" data-clipboard-text=\""
- + alias4(((helper = (helper = helpers.shareLinkURL || (depth0 != null ? depth0.shareLinkURL : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareLinkURL","hash":{},"data":data}) : helper)))
- + "\">\n <span class=\"icon icon-clippy\" ></span>\n <span>"
- + alias4(((helper = (helper = helpers.copyLabel || (depth0 != null ? depth0.copyLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"copyLabel","hash":{},"data":data}) : helper)))
- + "</span>\n </a>\n </li>\n <li class=\"hidden linkTextMenu\">\n <span class=\"menuitem icon-link-text\">\n <input id=\"linkText-"
+ return "<div class=\"popovermenu menu\">\n <ul>\n <li class=\"hidden linkTextMenu\">\n <span class=\"menuitem icon-link-text\">\n <input id=\"linkText-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\" class=\"linkText\" type=\"text\" readonly=\"readonly\" value=\""
+ alias4(((helper = (helper = helpers.shareLinkURL || (depth0 != null ? depth0.shareLinkURL : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareLinkURL","hash":{},"data":data}) : helper)))
+ "\" />\n </span>\n </li>\n"
+ ((stack1 = helpers["if"].call(alias1,(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(alias1,(depth0 != null ? depth0.publicEditing : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showPasswordCheckBox : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " <li>\n <span class=\"shareOption menuitem\">\n <input id=\"expireDate-"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showHideDownloadCheckbox : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showPasswordCheckBox : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.showPasswordByTalkCheckBox : depth0),{"name":"if","hash":{},"fn":container.program(13, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " <li>\n <span class=\"menuitem\">\n <input id=\"expireDate-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\" type=\"checkbox\" name=\"expirationDate\" class=\"expireDate checkbox\"\n "
+ ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ " "
- + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + "\" />\n <label for=\"expireDate-"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " />\n <label for=\"expireDate-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.expireDateLabel || (depth0 != null ? depth0.expireDateLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"expireDateLabel","hash":{},"data":data}) : helper)))
+ "</label>\n </span>\n </li>\n <li class=\""
- + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"unless","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"unless","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ "\">\n <span class=\"menuitem icon-expiredate expirationDateContainer-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "\">\n <label for=\"expirationDatePicker-"
@@ -185,40 +226,50 @@ templates['sharedialoglinkshareview_popover_menu'] = template({"1":function(cont
+ alias4(((helper = (helper = helpers.expirationDate || (depth0 != null ? depth0.expirationDate : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"expirationDate","hash":{},"data":data}) : helper)))
+ "\">"
+ alias4(((helper = (helper = helpers.expirationLabel || (depth0 != null ? depth0.expirationLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"expirationLabel","hash":{},"data":data}) : helper)))
- + "</label>\n <input id=\"expirationDatePicker-"
+ + "</label>\n <!-- do not use the datepicker if enforced -->\n <input id=\"expirationDatePicker-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
- + "\" class=\"datepicker\" type=\"text\" placeholder=\""
+ + "\" class=\""
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"unless","hash":{},"fn":container.program(15, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\" type=\"text\"\n placeholder=\""
+ alias4(((helper = (helper = helpers.expirationDatePlaceholder || (depth0 != null ? depth0.expirationDatePlaceholder : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"expirationDatePlaceholder","hash":{},"data":data}) : helper)))
+ "\" value=\""
- + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.program(14, data, 0),"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>"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasExpireDate : depth0),{"name":"if","hash":{},"fn":container.program(17, data, 0),"inverse":container.program(19, data, 0),"data":data})) != null ? stack1 : "")
+ + "\"\n data-max-date=\""
+ + alias4(((helper = (helper = helpers.maxDate || (depth0 != null ? depth0.maxDate : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"maxDate","hash":{},"data":data}) : helper)))
+ + "\" "
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isExpirationEnforced : depth0),{"name":"if","hash":{},"fn":container.program(21, 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>"
+ alias4(((helper = (helper = helpers.addNoteLabel || (depth0 != null ? depth0.addNoteLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"addNoteLabel","hash":{},"data":data}) : helper)))
- + "</span>\n <input type=\"button\" class=\"share-note-delete icon-delete\">\n </a>\n </li>\n <li class=\"share-note-form share-note-link hidden\">\n <span class=\"menuitem icon-note\">\n <textarea class=\"share-note\">"
+ + "</span>\n <input type=\"button\" class=\"share-note-delete icon-delete "
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasNote : depth0),{"name":"unless","hash":{},"fn":container.program(11, 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(alias1,(depth0 != null ? depth0.hasNote : depth0),{"name":"unless","hash":{},"fn":container.program(11, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\">\n <span class=\"menuitem icon-note\">\n <textarea class=\"share-note\">"
+ alias4(((helper = (helper = helpers.shareNote || (depth0 != null ? depth0.shareNote : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareNote","hash":{},"data":data}) : helper)))
+ "</textarea>\n <input type=\"submit\" class=\"icon-confirm share-note-submit\" value=\"\" id=\"add-note-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
- + "\" />\n </span>\n </li>\n"
- + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(16, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + " </ul>\n</div>\n";
+ + "\" />\n </span>\n </li>\n"
+ + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.social : depth0),{"name":"each","hash":{},"fn":container.program(23, 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>"
+ + alias4(((helper = (helper = helpers.unshareLinkLabel || (depth0 != null ? depth0.unshareLinkLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"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>"
+ + alias4(((helper = (helper = helpers.newShareLabel || (depth0 != null ? depth0.newShareLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"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=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li><span class=\"shareOption menuitem\">\n <input type=\"checkbox\" name=\"showPassword\" id=\"showPassword-"
- + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
- + "\" checked=\"checked\" disabled class=\"checkbox showPasswordCheckbox\" value=\"1\" />\n <label for=\"showPassword-"
- + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
- + "\">"
- + alias4(((helper = (helper = helpers.enablePasswordLabel || (depth0 != null ? depth0.enablePasswordLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"enablePasswordLabel","hash":{},"data":data}) : helper)))
- + "</label>\n </span></li>\n <li class=\"linkPassMenu\"><span class=\"shareOption menuitem icon-share-pass\">\n <input id=\"linkPassText-"
- + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
- + "\" class=\"linkPassText\" type=\"password\" placeholder=\""
+ return " <li>\n <span class=\"menuitem icon-info\">\n <p>"
+ + alias4(((helper = (helper = helpers.enforcedPasswordLabel || (depth0 != null ? depth0.enforcedPasswordLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"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=\""
+ alias4(((helper = (helper = helpers.passwordPlaceholder || (depth0 != null ? depth0.passwordPlaceholder : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"passwordPlaceholder","hash":{},"data":data}) : helper)))
- + "\" autocomplete=\"new-password\" />\n <span class=\"icon icon-loading-small hidden\"></span>\n </span></li>\n";
+ + "\" autocomplete=\"enforcedPassText\" minlength=\""
+ + alias4(((helper = (helper = helpers.minPasswordLength || (depth0 != null ? depth0.minPasswordLength : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"minPasswordLength","hash":{},"data":data}) : helper)))
+ + "\" />\n <input type=\"submit\" value=\" \" class=\"primary icon-checkmark-white\">\n </form>\n </span>\n </li>\n";
},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1;
- return "<div class=\"popovermenu pendingpopover menu\">\n <ul>\n"
+ return "<div class=\"popovermenu open menu\">\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});
@@ -280,7 +331,7 @@ templates['sharedialogshareelistview'] = template({"1":function(container,depth0
},"6":function(container,depth0,helpers,partials,data) {
var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <span class=\"shareOption\">\n <input id=\"canEdit-"
+ return " <span>\n <input id=\"canEdit-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -330,7 +381,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
},"3":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return "\n <li>\n <span class=\"shareOption menuitem\">\n <input id=\"canShare-"
+ return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canShare-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -364,7 +415,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
},"8":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return "\n <li>\n <span class=\"shareOption menuitem\">\n <input id=\"canCreate-"
+ return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canCreate-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -386,7 +437,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
},"11":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return "\n <li>\n <span class=\"shareOption menuitem\">\n <input id=\"canUpdate-"
+ return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canUpdate-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -408,7 +459,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
},"14":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return "\n <li>\n <span class=\"shareOption menuitem\">\n <input id=\"canDelete-"
+ return "\n <li>\n <span class=\"menuitem\">\n <input id=\"canDelete-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -427,7 +478,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
return ((stack1 = helpers["if"].call(alias1,(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=\"shareOption menuitem\">\n <input id=\"password-"
+ + " <li>\n <span class=\"menuitem\">\n <input id=\"password-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -471,7 +522,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
},"17":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li>\n <span class=\"shareOption menuitem\">\n <input id=\"secureDrop-"
+ return " <li>\n <span class=\"menuitem\">\n <input id=\"secureDrop-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -497,7 +548,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
},"24":function(container,depth0,helpers,partials,data) {
var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li>\n <span class=\"shareOption menuitem\">\n <input id=\"passwordByTalk-"
+ return " <li>\n <span class=\"menuitem\">\n <input id=\"passwordByTalk-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -545,11 +596,15 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
return container.escapeExpression(((helper = (helper = helpers.defaultExpireDate || (depth0 != null ? depth0.defaultExpireDate : depth0)) != null ? helper : helpers.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 helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
- return " <li>\n <a href=\"#\" class=\"share-add\"><span class=\"icon-loading-small hidden\"></span>\n <span class=\"icon icon-edit\"></span>\n <span>"
+ 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>"
+ alias4(((helper = (helper = helpers.addNoteLabel || (depth0 != null ? depth0.addNoteLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"addNoteLabel","hash":{},"data":data}) : helper)))
- + "</span>\n <input type=\"button\" class=\"share-note-delete icon-delete\">\n </a>\n </li>\n <li class=\"share-note-form hidden\">\n <span class=\"menuitem icon-note\">\n <textarea class=\"share-note\">"
+ + "</span>\n <input type=\"button\" class=\"share-note-delete icon-delete "
+ + ((stack1 = helpers.unless.call(alias1,(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(alias1,(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\">"
+ alias4(((helper = (helper = helpers.shareNote || (depth0 != null ? depth0.shareNote : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareNote","hash":{},"data":data}) : helper)))
+ "</textarea>\n <input type=\"submit\" class=\"icon-confirm share-note-submit\" value=\"\" id=\"add-note-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
@@ -562,7 +617,7 @@ templates['sharedialogshareelistview_popover_menu'] = template({"1":function(con
+ "\n"
+ ((stack1 = helpers["if"].call(alias1,(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(alias1,(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=\"shareOption menuitem\">\n <input id=\"expireDate-"
+ + " <li>\n <span class=\"menuitem\">\n <input id=\"expireDate-"
+ alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ "-"
+ alias4(((helper = (helper = helpers.shareId || (depth0 != null ? depth0.shareId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"shareId","hash":{},"data":data}) : helper)))
diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js
index f2fc2888448..45a0f04db00 100644
--- a/core/js/tests/specHelper.js
+++ b/core/js/tests/specHelper.js
@@ -103,6 +103,8 @@ window.oc_appconfig = {
window.oc_defaults = {
docPlaceholderUrl: 'https://docs.example.org/PLACEHOLDER'
};
+window.oc_capabilities = {
+}
/* jshint camelcase: true */
diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js
index 67b7d77be6c..63c02048a34 100644
--- a/core/js/tests/specs/coreSpec.js
+++ b/core/js/tests/specs/coreSpec.js
@@ -573,6 +573,10 @@ describe('Core base tests', function() {
});
it('Clicking menu toggle toggles navigation in', function() {
window.initCore();
+ // fore show more apps icon since otherwise it would be hidden since no icons are available
+ clock.tick(1 * 1000);
+ $('#more-apps').show();
+
expect($navigation.is(':visible')).toEqual(false);
$toggle.click();
clock.tick(1 * 1000);
diff --git a/core/js/tests/specs/sharedialoglinkshareview.js b/core/js/tests/specs/sharedialoglinkshareview.js
index 9d07dcb479d..c2d84fd2e87 100644
--- a/core/js/tests/specs/sharedialoglinkshareview.js
+++ b/core/js/tests/specs/sharedialoglinkshareview.js
@@ -72,6 +72,102 @@ describe('OC.Share.ShareDialogLinkShareView', function () {
configModel.isShareWithLinkAllowed.restore();
});
+ describe('hide download', function () {
+
+ var $hideDownloadCheckbox;
+ var $workingIcon;
+
+ beforeEach(function () {
+ // Needed to render the view
+ configModel.isShareWithLinkAllowed.returns(true);
+
+ shareModel.set({
+ linkShares: [{
+ id: 123
+ }]
+ });
+ view.render();
+
+ $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
+ $workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small');
+
+ sinon.stub(shareModel, 'saveLinkShare');
+
+ expect($workingIcon.hasClass('hidden')).toBeTruthy();
+ });
+
+ afterEach(function () {
+ shareModel.saveLinkShare.restore();
+ });
+
+ it('is shown if the share is a file', function() {
+ expect($hideDownloadCheckbox.length).toBeTruthy();
+ });
+
+ it('is not shown if the share is a folder', function() {
+ shareModel.fileInfoModel.set('mimetype', 'httpd/unix-directory');
+
+ // Setting the item type also triggers the rendering
+ shareModel.set({
+ itemType: 'folder'
+ });
+
+ $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
+
+ expect($hideDownloadCheckbox.length).toBeFalsy();
+ });
+
+ it('checkbox is checked when the setting is enabled', function () {
+ shareModel.set({
+ linkShares: [{
+ id: 123,
+ hideDownload: true
+ }]
+ });
+ view.render();
+
+ $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
+
+ expect($hideDownloadCheckbox.is(':checked')).toEqual(true);
+ });
+
+ it('checkbox is not checked when the setting is disabled', function () {
+ expect($hideDownloadCheckbox.is(':checked')).toEqual(false);
+ });
+
+ it('enables the setting if clicked when unchecked', function () {
+ // Simulate the click by checking the checkbox and then triggering
+ // the "change" event.
+ $hideDownloadCheckbox.prop('checked', true);
+ $hideDownloadCheckbox.change();
+
+ expect($workingIcon.hasClass('hidden')).toBeFalsy();
+ expect(shareModel.saveLinkShare.withArgs({ hideDownload: true, cid: 123 }).calledOnce).toBeTruthy();
+ });
+
+ it('disables the setting if clicked when checked', function () {
+ shareModel.set({
+ linkShares: [{
+ id: 123,
+ hideDownload: true
+ }]
+ });
+ view.render();
+
+ $hideDownloadCheckbox = view.$el.find('.hideDownloadCheckbox');
+ $workingIcon = $hideDownloadCheckbox.prev('.icon-loading-small');
+
+ // Simulate the click by unchecking the checkbox and then triggering
+ // the "change" event.
+ $hideDownloadCheckbox.prop('checked', false);
+ $hideDownloadCheckbox.change();
+
+ expect($workingIcon.hasClass('hidden')).toBeFalsy();
+ expect(shareModel.saveLinkShare.withArgs({ hideDownload: false, cid: 123 }).calledOnce).toBeTruthy();
+ });
+
+ });
+
describe('onPasswordEntered', function () {
var $passwordText;
@@ -82,13 +178,13 @@ describe('OC.Share.ShareDialogLinkShareView', function () {
// Needed to render the view
configModel.isShareWithLinkAllowed.returns(true);
- // Setting the share also triggers the rendering
shareModel.set({
- linkShare: {
- isLinkShare: true,
+ linkShares: [{
+ id: 123,
password: 'password'
- }
+ }]
});
+ view.render();
var $passwordDiv = view.$el.find('#linkPass');
$passwordText = view.$el.find('.linkPassText');
@@ -108,17 +204,17 @@ describe('OC.Share.ShareDialogLinkShareView', function () {
});
it('shows the working icon when called', function () {
- view.onPasswordEntered();
+ view.onPasswordEntered({target: view.$el.find('.linkPassText')});
expect($workingIcon.hasClass('hidden')).toBeFalsy();
- expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword' }).calledOnce).toBeTruthy();
+ expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy();
});
it('hides the working icon when saving the password succeeds', function () {
- view.onPasswordEntered();
+ view.onPasswordEntered({target: view.$el.find('.linkPassText')});
expect($workingIcon.hasClass('hidden')).toBeFalsy();
- expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword' }).calledOnce).toBeTruthy();
+ expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy();
shareModel.saveLinkShare.yieldTo("complete", [shareModel]);
@@ -126,10 +222,10 @@ describe('OC.Share.ShareDialogLinkShareView', function () {
});
it('hides the working icon when saving the password fails', function () {
- view.onPasswordEntered();
+ view.onPasswordEntered({target: view.$el.find('.linkPassText')});
expect($workingIcon.hasClass('hidden')).toBeFalsy();
- expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword' }).calledOnce).toBeTruthy();
+ expect(shareModel.saveLinkShare.withArgs({ password: 'myPassword', cid: 123 }).calledOnce).toBeTruthy();
shareModel.saveLinkShare.yieldTo("complete", [shareModel]);
shareModel.saveLinkShare.yieldTo("error", [shareModel, "The error message"]);
@@ -139,4 +235,117 @@ describe('OC.Share.ShareDialogLinkShareView', function () {
});
+ describe('protect password by Talk', function () {
+
+ var $passwordByTalkCheckbox;
+ var $workingIcon;
+
+ beforeEach(function () {
+ // Needed to render the view
+ configModel.isShareWithLinkAllowed.returns(true);
+
+ // "Enable" Talk
+ window.oc_appswebroots['spreed'] = window.oc_webroot + '/apps/files/';
+
+ shareModel.set({
+ linkShares: [{
+ id: 123,
+ password: 'password'
+ }]
+ });
+ view.render();
+
+ $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
+ $workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small');
+
+ sinon.stub(shareModel, 'saveLinkShare');
+
+ expect($workingIcon.hasClass('hidden')).toBeTruthy();
+ });
+
+ afterEach(function () {
+ shareModel.saveLinkShare.restore();
+ });
+
+ it('is shown if Talk is enabled and there is a password set', function() {
+ expect($passwordByTalkCheckbox.length).toBeTruthy();
+ });
+
+ it('is not shown if Talk is enabled but there is no password set', function() {
+ // Changing the password value also triggers the rendering
+ shareModel.set({
+ linkShares: [{
+ id: 123
+ }]
+ });
+
+ $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
+
+ expect($passwordByTalkCheckbox.length).toBeFalsy();
+ });
+
+ it('is not shown if there is a password set but Talk is not enabled', function() {
+ // "Disable" Talk
+ delete window.oc_appswebroots['spreed'];
+
+ view.render();
+
+ $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
+
+ expect($passwordByTalkCheckbox.length).toBeFalsy();
+ });
+
+ it('checkbox is checked when the setting is enabled', function () {
+ shareModel.set({
+ linkShares: [{
+ id: 123,
+ password: 'password',
+ sendPasswordByTalk: true
+ }]
+ });
+ view.render();
+
+ $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
+
+ expect($passwordByTalkCheckbox.is(':checked')).toEqual(true);
+ });
+
+ it('checkbox is not checked when the setting is disabled', function () {
+ expect($passwordByTalkCheckbox.is(':checked')).toEqual(false);
+ });
+
+ it('enables the setting if clicked when unchecked', function () {
+ // Simulate the click by checking the checkbox and then triggering
+ // the "change" event.
+ $passwordByTalkCheckbox.prop('checked', true);
+ $passwordByTalkCheckbox.change();
+
+ expect($workingIcon.hasClass('hidden')).toBeFalsy();
+ expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: true, cid: 123 }).calledOnce).toBeTruthy();
+ });
+
+ it('disables the setting if clicked when checked', function () {
+ shareModel.set({
+ linkShares: [{
+ id: 123,
+ password: 'password',
+ sendPasswordByTalk: true
+ }]
+ });
+ view.render();
+
+ $passwordByTalkCheckbox = view.$el.find('.passwordByTalkCheckbox');
+ $workingIcon = $passwordByTalkCheckbox.prev('.icon-loading-small');
+
+ // Simulate the click by unchecking the checkbox and then triggering
+ // the "change" event.
+ $passwordByTalkCheckbox.prop('checked', false);
+ $passwordByTalkCheckbox.change();
+
+ expect($workingIcon.hasClass('hidden')).toBeFalsy();
+ expect(shareModel.saveLinkShare.withArgs({ sendPasswordByTalk: false, cid: 123 }).calledOnce).toBeTruthy();
+ });
+
+ });
+
});
diff --git a/core/js/tests/specs/sharedialogshareelistview.js b/core/js/tests/specs/sharedialogshareelistview.js
index 8e34225d199..4f84fa0e08f 100644
--- a/core/js/tests/specs/sharedialogshareelistview.js
+++ b/core/js/tests/specs/sharedialogshareelistview.js
@@ -73,7 +73,7 @@ describe('OC.Share.ShareDialogShareeListView', function () {
$('#testArea').append(listView.$el);
shareModel.set({
- linkShare: {isLinkShare: false}
+ linkShares: []
});
oldCurrentUser = OC.currentUser;
@@ -90,6 +90,37 @@ describe('OC.Share.ShareDialogShareeListView', function () {
});
describe('Sets correct initial checkbox state', function () {
+
+ it('marks edit box as unchecked for file shares without edit permissions', function () {
+ shareModel.set('shares', [{
+ id: 100,
+ item_source: 123,
+ permissions: 1,
+ share_type: OC.Share.SHARE_TYPE_USER,
+ share_with: 'user1',
+ share_with_displayname: 'User One',
+ uid_owner: oc_current_user,
+ itemType: 'file'
+ }]);
+ listView.render();
+ expect(listView.$el.find("input[name='edit']").is(':not(:checked)')).toEqual(true);
+ });
+
+ it('marks edit box as checked for file shares', function () {
+ shareModel.set('shares', [{
+ id: 100,
+ item_source: 123,
+ permissions: 1 | OC.PERMISSION_UPDATE,
+ share_type: OC.Share.SHARE_TYPE_USER,
+ share_with: 'user1',
+ share_with_displayname: 'User One',
+ uid_owner: oc_current_user,
+ itemType: 'file'
+ }]);
+ listView.render();
+ expect(listView.$el.find("input[name='edit']").is(':checked')).toEqual(true);
+ });
+
it('marks edit box as indeterminate when only some permissions are given', function () {
shareModel.set('shares', [{
id: 100,
diff --git a/core/js/tests/specs/sharedialogviewSpec.js b/core/js/tests/specs/sharedialogviewSpec.js
index efe50c415c8..8d5a2ae434d 100644
--- a/core/js/tests/specs/sharedialogviewSpec.js
+++ b/core/js/tests/specs/sharedialogviewSpec.js
@@ -89,7 +89,7 @@ describe('OC.Share.ShareDialogView', function() {
// triggers rendering
shareModel.set({
shares: [],
- linkShare: {isLinkShare: false}
+ linkShares: []
});
autocompleteStub = sinon.stub($.fn, 'autocomplete').callsFake(function() {
@@ -130,8 +130,10 @@ describe('OC.Share.ShareDialogView', function() {
it('update password on focus out', function() {
$('#allowShareWithLink').val('yes');
- dialog.model.set('linkShare', {
- isLinkShare: true
+ dialog.model.set({
+ linkShares: [{
+ id: 123
+ }]
});
dialog.render();
@@ -143,20 +145,20 @@ describe('OC.Share.ShareDialogView', function() {
expect(saveLinkShareStub.calledOnce).toEqual(true);
expect(saveLinkShareStub.firstCall.args[0]).toEqual({
+ cid: 123,
password: 'foo'
});
});
it('update password on enter', function() {
$('#allowShareWithLink').val('yes');
- dialog.model.set('linkShare', {
- isLinkShare: true
+ dialog.model.set({
+ linkShares: [{
+ id: 123
+ }]
});
dialog.render();
- // Toggle linkshare
- dialog.$el.find('.linkCheckbox').click();
-
// Enable password and enter password
dialog.$el.find('[name=showPassword]').click();
dialog.$el.find('.linkPassText').focus();
@@ -165,47 +167,48 @@ describe('OC.Share.ShareDialogView', function() {
expect(saveLinkShareStub.calledOnce).toEqual(true);
expect(saveLinkShareStub.firstCall.args[0]).toEqual({
+ cid: 123,
password: 'foo'
});
});
- it('shows share with link checkbox when allowed', function() {
+ it('shows add share with link button when allowed', function() {
$('#allowShareWithLink').val('yes');
dialog.render();
- expect(dialog.$el.find('.linkCheckbox').length).toEqual(1);
+ expect(dialog.$el.find('.new-share').length).toEqual(1);
});
- it('does not show share with link checkbox when not allowed', function() {
+ it('does not show add share with link button when not allowed', function() {
$('#allowShareWithLink').val('no');
dialog.render();
- expect(dialog.$el.find('.linkCheckbox').length).toEqual(0);
+ expect(dialog.$el.find('.new-share').length).toEqual(0);
expect(dialog.$el.find('.shareWithField').length).toEqual(1);
});
it('shows populated link share when a link share exists', function() {
// this is how the OC.Share class does it...
var link = parent.location.protocol + '//' + location.host +
- OC.generateUrl('/s/') + 'tehtoken';
- shareModel.set('linkShare', {
- isLinkShare: true,
- token: 'tehtoken',
- link: link,
- expiration: '',
- permissions: OC.PERMISSION_READ,
- stime: 1403884258,
+ OC.generateUrl('/s/') + 'thetoken';
+ shareModel.set({
+ linkShares: [{
+ id: 123,
+ url: link
+ }]
});
dialog.render();
- expect(dialog.$el.find('.linkCheckbox').prop('checked')).toEqual(true);
+ expect(dialog.$el.find('.share-menu .icon-more').length).toEqual(1);
expect(dialog.$el.find('.linkText').val()).toEqual(link);
});
it('autofocus link text when clicked', function() {
$('#allowShareWithLink').val('yes');
- dialog.model.set('linkShare', {
- isLinkShare: true
+ dialog.model.set({
+ linkShares: [{
+ id: 123
+ }]
});
dialog.render();
diff --git a/core/js/tests/specs/shareitemmodelSpec.js b/core/js/tests/specs/shareitemmodelSpec.js
index 2e89b2e3cda..e8016950094 100644
--- a/core/js/tests/specs/shareitemmodelSpec.js
+++ b/core/js/tests/specs/shareitemmodelSpec.js
@@ -168,7 +168,9 @@ describe('OC.Share.ShareItemModel', function() {
stime: 1403884258,
storage: 1,
token: 'tehtoken',
- uid_owner: 'root'
+ uid_owner: 'root',
+ hide_download: 1,
+ send_password_by_talk: true
}
]));
@@ -184,8 +186,11 @@ describe('OC.Share.ShareItemModel', function() {
expect(shares[0].share_with).toEqual('user1');
expect(shares[0].share_with_displayname).toEqual('User One');
- var linkShare = model.get('linkShare');
- expect(linkShare.isLinkShare).toEqual(true);
+ var linkShares = model.get('linkShares');
+ expect(linkShares.length).toEqual(1);
+ var linkShare = linkShares[0];
+ expect(linkShare.hideDownload).toEqual(true);
+ expect(linkShare.sendPasswordByTalk).toEqual(true);
// TODO: check more attributes
});
@@ -266,8 +271,8 @@ describe('OC.Share.ShareItemModel', function() {
// remaining share appears in this list
expect(shares.length).toEqual(1);
- var linkShare = model.get('linkShare');
- expect(linkShare.isLinkShare).toEqual(false);
+ var linkShares = model.get('linkShares');
+ expect(linkShares.length).toEqual(0);
});
it('parses correct link share when a nested link share exists along with parent one', function() {
/* jshint camelcase: false */
@@ -289,7 +294,9 @@ describe('OC.Share.ShareItemModel', function() {
stime: 1403884258,
storage: 1,
token: 'tehtoken',
- uid_owner: 'root'
+ uid_owner: 'root',
+ hide_download: 0,
+ send_password_by_talk: false
}, {
displayname_owner: 'root',
expiration: '2015-10-15 00:00:00',
@@ -307,7 +314,9 @@ describe('OC.Share.ShareItemModel', function() {
stime: 1403884509,
storage: 1,
token: 'anothertoken',
- uid_owner: 'root'
+ uid_owner: 'root',
+ hide_download: 1,
+ send_password_by_talk: true
}]
));
OC.currentUser = 'root';
@@ -317,9 +326,12 @@ describe('OC.Share.ShareItemModel', function() {
// the parent share remains in the list
expect(shares.length).toEqual(1);
- var linkShare = model.get('linkShare');
- expect(linkShare.isLinkShare).toEqual(true);
+ var linkShares = model.get('linkShares');
+ expect(linkShares.length).toEqual(1);
+ var linkShare = linkShares[0];
expect(linkShare.token).toEqual('tehtoken');
+ expect(linkShare.hideDownload).toEqual(false);
+ expect(linkShare.sendPasswordByTalk).toEqual(false);
// TODO: check child too
});
@@ -570,17 +582,18 @@ describe('OC.Share.ShareItemModel', function() {
it('creates a new share if no link share exists', function() {
model.set({
- linkShare: {
- isLinkShare: false
- }
+ linkShares: [
+ ]
});
model.saveLinkShare();
expect(addShareStub.calledOnce).toEqual(true);
expect(addShareStub.firstCall.args[0]).toEqual({
+ hideDownload: false,
password: '',
passwordChanged: false,
+ sendPasswordByTalk: false,
permissions: OC.PERMISSION_READ,
expireDate: '',
shareType: OC.Share.SHARE_TYPE_LINK
@@ -594,17 +607,18 @@ describe('OC.Share.ShareItemModel', function() {
defaultExpireDate: 7
});
model.set({
- linkShare: {
- isLinkShare: false
- }
+ linkShares: [
+ ]
});
model.saveLinkShare();
expect(addShareStub.calledOnce).toEqual(true);
expect(addShareStub.firstCall.args[0]).toEqual({
+ hideDownload: false,
password: '',
passwordChanged: false,
+ sendPasswordByTalk: false,
permissions: OC.PERMISSION_READ,
expireDate: '2015-07-24 00:00:00',
shareType: OC.Share.SHARE_TYPE_LINK
@@ -614,13 +628,13 @@ describe('OC.Share.ShareItemModel', function() {
});
it('updates link share if it exists', function() {
model.set({
- linkShare: {
- isLinkShare: true,
+ linkShares: [{
id: 123
- }
+ }]
});
model.saveLinkShare({
+ cid: 123,
password: 'test'
});
@@ -628,20 +642,19 @@ describe('OC.Share.ShareItemModel', function() {
expect(updateShareStub.calledOnce).toEqual(true);
expect(updateShareStub.firstCall.args[0]).toEqual(123);
expect(updateShareStub.firstCall.args[1]).toEqual({
+ cid: 123,
password: 'test'
});
});
it('forwards error message on add', function() {
var errorStub = sinon.stub();
model.set({
- linkShare: {
- isLinkShare: false
- }
+ linkShares: [
+ ]
}, {
});
model.saveLinkShare({
- password: 'test'
}, {
error: errorStub
});
@@ -654,14 +667,14 @@ describe('OC.Share.ShareItemModel', function() {
it('forwards error message on update', function() {
var errorStub = sinon.stub();
model.set({
- linkShare: {
- isLinkShare: true,
- id: '123'
- }
+ linkShares: [{
+ id: 123
+ }]
}, {
});
model.saveLinkShare({
+ cid: 123,
password: 'test'
}, {
error: errorStub