You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sharedialoglinkshareview.js 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * Copyright (c) 2015
  3. *
  4. * This file is licensed under the Affero General Public License version 3
  5. * or later.
  6. *
  7. * See the COPYING-README file.
  8. *
  9. */
  10. (function() {
  11. if (!OC.Share) {
  12. OC.Share = {};
  13. }
  14. var PASSWORD_PLACEHOLDER = '**********';
  15. var PASSWORD_PLACEHOLDER_MESSAGE = t('core', 'Choose a password for the public link');
  16. var TEMPLATE =
  17. '{{#if shareAllowed}}' +
  18. '<span class="icon-loading-small hidden"></span>' +
  19. '<input type="checkbox" name="linkCheckbox" id="linkCheckbox-{{cid}}" class="checkbox linkCheckbox" value="1" {{#if isLinkShare}}checked="checked"{{/if}} />' +
  20. '<label for="linkCheckbox-{{cid}}">{{linkShareLabel}}</label>' +
  21. '<br />' +
  22. '<label for="linkText-{{cid}}" class="hidden-visually">{{urlLabel}}</label>' +
  23. '<input id="linkText-{{cid}}" class="linkText {{#unless isLinkShare}}hidden{{/unless}}" type="text" readonly="readonly" value="{{shareLinkURL}}" />' +
  24. ' {{#if publicUpload}}' +
  25. '<div id="allowPublicUploadWrapper">' +
  26. ' <span class="icon-loading-small hidden"></span>' +
  27. ' <input type="checkbox" value="1" name="allowPublicUpload" id="sharingDialogAllowPublicUpload-{{cid}}" class="checkbox publicUploadCheckbox" {{{publicUploadChecked}}} />' +
  28. '<label for="sharingDialogAllowPublicUpload-{{cid}}">{{publicUploadLabel}}</label>' +
  29. '</div>' +
  30. ' {{#if hideFileList}}' +
  31. '<div id="hideFileListWrapper">' +
  32. ' <span class="icon-loading-small hidden"></span>' +
  33. ' <input type="checkbox" value="1" name="hideFileList" id="sharingDialogHideFileList-{{cid}}" class="checkbox hideFileListCheckbox" {{{hideFileListChecked}}} />' +
  34. '<label for="sharingDialogHideFileList-{{cid}}">{{hideFileListLabel}}</label>' +
  35. '</div>' +
  36. ' {{/if}}' +
  37. ' {{/if}}' +
  38. ' {{#if showPasswordCheckBox}}' +
  39. '<input type="checkbox" name="showPassword" id="showPassword-{{cid}}" class="checkbox showPasswordCheckbox" {{#if isPasswordSet}}checked="checked"{{/if}} value="1" />' +
  40. '<label for="showPassword-{{cid}}">{{enablePasswordLabel}}</label>' +
  41. ' {{/if}}' +
  42. '<div id="linkPass" class="linkPass {{#unless isPasswordSet}}hidden{{/unless}}">' +
  43. ' <label for="linkPassText-{{cid}}" class="hidden-visually">{{passwordLabel}}</label>' +
  44. ' <input id="linkPassText-{{cid}}" class="linkPassText" type="password" placeholder="{{passwordPlaceholder}}" />' +
  45. ' <span class="icon-loading-small hidden"></span>' +
  46. '</div>' +
  47. '{{else}}' +
  48. // FIXME: this doesn't belong in this view
  49. '{{#if noSharingPlaceholder}}<input id="shareWith-{{cid}}" class="shareWithField" type="text" placeholder="{{noSharingPlaceholder}}" disabled="disabled"/>{{/if}}' +
  50. '{{/if}}'
  51. ;
  52. /**
  53. * @class OCA.Share.ShareDialogLinkShareView
  54. * @member {OC.Share.ShareItemModel} model
  55. * @member {jQuery} $el
  56. * @memberof OCA.Sharing
  57. * @classdesc
  58. *
  59. * Represents the GUI of the share dialogue
  60. *
  61. */
  62. var ShareDialogLinkShareView = OC.Backbone.View.extend({
  63. /** @type {string} **/
  64. id: 'shareDialogLinkShare',
  65. /** @type {OC.Share.ShareConfigModel} **/
  66. configModel: undefined,
  67. /** @type {Function} **/
  68. _template: undefined,
  69. /** @type {boolean} **/
  70. showLink: true,
  71. events: {
  72. 'focusout input.linkPassText': 'onPasswordEntered',
  73. 'keyup input.linkPassText': 'onPasswordKeyUp',
  74. 'click .linkCheckbox': 'onLinkCheckBoxChange',
  75. 'click .linkText': 'onLinkTextClick',
  76. 'change .publicUploadCheckbox': 'onAllowPublicUploadChange',
  77. 'change .hideFileListCheckbox': 'onHideFileListChange',
  78. 'click .showPasswordCheckbox': 'onShowPasswordClick'
  79. },
  80. initialize: function(options) {
  81. var view = this;
  82. this.model.on('change:permissions', function() {
  83. view.render();
  84. });
  85. this.model.on('change:itemType', function() {
  86. view.render();
  87. });
  88. this.model.on('change:allowPublicUploadStatus', function() {
  89. view.render();
  90. });
  91. this.model.on('change:hideFileListStatus', function() {
  92. view.render();
  93. });
  94. this.model.on('change:linkShare', function() {
  95. view.render();
  96. });
  97. if(!_.isUndefined(options.configModel)) {
  98. this.configModel = options.configModel;
  99. } else {
  100. throw 'missing OC.Share.ShareConfigModel';
  101. }
  102. _.bindAll(
  103. this,
  104. 'onLinkCheckBoxChange',
  105. 'onPasswordEntered',
  106. 'onPasswordKeyUp',
  107. 'onLinkTextClick',
  108. 'onShowPasswordClick',
  109. 'onHideFileListChange',
  110. 'onAllowPublicUploadChange'
  111. );
  112. },
  113. onLinkCheckBoxChange: function() {
  114. var $checkBox = this.$el.find('.linkCheckbox');
  115. var $loading = $checkBox.siblings('.icon-loading-small');
  116. if(!$loading.hasClass('hidden')) {
  117. return false;
  118. }
  119. if($checkBox.is(':checked')) {
  120. if(this.configModel.get('enforcePasswordForPublicLink') === false) {
  121. $loading.removeClass('hidden');
  122. // this will create it
  123. this.model.saveLinkShare();
  124. } else {
  125. this.$el.find('.linkPass').slideToggle(OC.menuSpeed);
  126. this.$el.find('.linkPassText').focus();
  127. }
  128. } else {
  129. if (this.model.get('linkShare').isLinkShare) {
  130. $loading.removeClass('hidden');
  131. this.model.removeLinkShare();
  132. } else {
  133. this.$el.find('.linkPass').slideToggle(OC.menuSpeed);
  134. }
  135. }
  136. },
  137. onLinkTextClick: function() {
  138. var $el = this.$el.find('.linkText');
  139. $el.focus();
  140. $el.select();
  141. },
  142. onShowPasswordClick: function() {
  143. this.$el.find('.linkPass').slideToggle(OC.menuSpeed);
  144. if(!this.$el.find('.showPasswordCheckbox').is(':checked')) {
  145. this.model.saveLinkShare({
  146. password: ''
  147. });
  148. } else {
  149. this.$el.find('.linkPassText').focus();
  150. }
  151. },
  152. onPasswordKeyUp: function(event) {
  153. if(event.keyCode == 13) {
  154. this.onPasswordEntered();
  155. }
  156. },
  157. onPasswordEntered: function() {
  158. var $loading = this.$el.find('.linkPass .icon-loading-small');
  159. if (!$loading.hasClass('hidden')) {
  160. // still in process
  161. return;
  162. }
  163. var $input = this.$el.find('.linkPassText');
  164. $input.removeClass('error');
  165. var password = $input.val();
  166. // in IE9 the password might be the placeholder due to bugs in the placeholders polyfill
  167. if(password === '' || password === PASSWORD_PLACEHOLDER || password === PASSWORD_PLACEHOLDER_MESSAGE) {
  168. return;
  169. }
  170. $loading
  171. .removeClass('hidden')
  172. .addClass('inlineblock');
  173. this.model.saveLinkShare({
  174. password: password
  175. }, {
  176. error: function(model, msg) {
  177. // destroy old tooltips
  178. $input.tooltip('destroy');
  179. $loading.removeClass('inlineblock').addClass('hidden');
  180. $input.addClass('error');
  181. $input.attr('title', msg);
  182. $input.tooltip({placement: 'bottom', trigger: 'manual'});
  183. $input.tooltip('show');
  184. }
  185. });
  186. },
  187. onAllowPublicUploadChange: function() {
  188. var $checkbox = this.$('.publicUploadCheckbox');
  189. $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');
  190. var permissions = OC.PERMISSION_READ;
  191. if($checkbox.is(':checked')) {
  192. permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ | OC.PERMISSION_DELETE;
  193. }
  194. this.model.saveLinkShare({
  195. permissions: permissions
  196. });
  197. },
  198. onHideFileListChange: function () {
  199. var $checkbox = this.$('.hideFileListCheckbox');
  200. $checkbox.siblings('.icon-loading-small').removeClass('hidden').addClass('inlineblock');
  201. var permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE | OC.PERMISSION_READ;
  202. if ($checkbox.is(':checked')) {
  203. permissions = OC.PERMISSION_UPDATE | OC.PERMISSION_CREATE;
  204. }
  205. this.model.saveLinkShare({
  206. permissions: permissions
  207. });
  208. },
  209. render: function() {
  210. var linkShareTemplate = this.template();
  211. var resharingAllowed = this.model.sharePermissionPossible();
  212. if(!resharingAllowed
  213. || !this.showLink
  214. || !this.configModel.isShareWithLinkAllowed())
  215. {
  216. var templateData = {shareAllowed: false};
  217. if (!resharingAllowed) {
  218. // add message
  219. templateData.noSharingPlaceholder = t('core', 'Resharing is not allowed');
  220. }
  221. this.$el.html(linkShareTemplate(templateData));
  222. return this;
  223. }
  224. var publicUpload =
  225. this.model.isFolder()
  226. && this.model.createPermissionPossible()
  227. && this.configModel.isPublicUploadEnabled();
  228. var publicUploadChecked = '';
  229. if(this.model.isPublicUploadAllowed()) {
  230. publicUploadChecked = 'checked="checked"';
  231. }
  232. var hideFileList = publicUploadChecked;
  233. var hideFileListChecked = '';
  234. if(this.model.isHideFileListSet()) {
  235. hideFileListChecked = 'checked="checked"';
  236. }
  237. var isLinkShare = this.model.get('linkShare').isLinkShare;
  238. var isPasswordSet = !!this.model.get('linkShare').password;
  239. var showPasswordCheckBox = isLinkShare
  240. && ( !this.configModel.get('enforcePasswordForPublicLink')
  241. || !this.model.get('linkShare').password);
  242. this.$el.html(linkShareTemplate({
  243. cid: this.cid,
  244. shareAllowed: true,
  245. hideFileList: hideFileList,
  246. isLinkShare: isLinkShare,
  247. shareLinkURL: this.model.get('linkShare').link,
  248. linkShareLabel: t('core', 'Share link'),
  249. urlLabel: t('core', 'Link'),
  250. enablePasswordLabel: t('core', 'Password protect'),
  251. passwordLabel: t('core', 'Password'),
  252. passwordPlaceholder: isPasswordSet ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
  253. isPasswordSet: isPasswordSet,
  254. showPasswordCheckBox: showPasswordCheckBox,
  255. publicUpload: publicUpload && isLinkShare,
  256. publicUploadChecked: publicUploadChecked,
  257. hideFileListChecked: hideFileListChecked,
  258. publicUploadLabel: t('core', 'Allow editing'),
  259. hideFileListLabel: t('core', 'Hide file listing'),
  260. mailPublicNotificationEnabled: isLinkShare && this.configModel.isMailPublicNotificationEnabled(),
  261. mailPrivatePlaceholder: t('core', 'Email link to person'),
  262. mailButtonText: t('core', 'Send')
  263. }));
  264. this.delegateEvents();
  265. return this;
  266. },
  267. /**
  268. * @returns {Function} from Handlebars
  269. * @private
  270. */
  271. template: function () {
  272. if (!this._template) {
  273. this._template = Handlebars.compile(TEMPLATE);
  274. }
  275. return this._template;
  276. }
  277. });
  278. OC.Share.ShareDialogLinkShareView = ShareDialogLinkShareView;
  279. })();