diff options
Diffstat (limited to 'core/js')
-rw-r--r-- | core/js/config.php | 17 | ||||
-rw-r--r-- | core/js/core.json | 1 | ||||
-rw-r--r-- | core/js/jquery.ocdialog.js | 18 | ||||
-rw-r--r-- | core/js/js.js | 113 | ||||
-rw-r--r-- | core/js/oc-dialogs.js | 67 | ||||
-rw-r--r-- | core/js/share.js | 129 | ||||
-rw-r--r-- | core/js/tests/specHelper.js | 3 | ||||
-rw-r--r-- | core/js/tests/specs/shareSpec.js | 97 | ||||
-rw-r--r-- | core/js/visitortimezone.js | 6 |
9 files changed, 413 insertions, 38 deletions
diff --git a/core/js/config.php b/core/js/config.php index 7e23f3e2e41..80b1b6d242d 100644 --- a/core/js/config.php +++ b/core/js/config.php @@ -25,6 +25,13 @@ foreach(OC_App::getEnabledApps() as $app) { $apps_paths[$app] = OC_App::getAppWebPath($app); } +$defaultExpireDateEnabled = \OCP\Config::getAppValue('core', 'shareapi_default_expire_date', 'no'); +$defaultExpireDate = $enforceDefaultExpireDate = null; +if ($defaultExpireDateEnabled === 'yes') { + $defaultExpireDate = \OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7'); + $enforceDefaultExpireDate = \OCP\Config::getAppValue('core', 'shareapi_enforce_expire_date', 'no'); +} + $array = array( "oc_debug" => (defined('DEBUG') && DEBUG) ? 'true' : 'false', "oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', @@ -67,6 +74,16 @@ $array = array( 'versionstring' => OC_Util::getVersionString(), ) ), + "oc_appconfig" => json_encode( + array("core" => array( + 'defaultExpireDateEnabled' => $defaultExpireDateEnabled, + 'defaultExpireDate' => $defaultExpireDate, + 'defaultExpireDateEnforced' => $enforceDefaultExpireDate, + 'enforcePasswordForPublicLink' => \OCP\Util::isPublicLinkPasswordRequired(), + 'sharingDisabledForUser' => \OCP\Util::isSharingDisabledForUser(), + ) + ) + ), "oc_defaults" => json_encode( array( 'entity' => $defaults->getEntity(), diff --git a/core/js/core.json b/core/js/core.json index 05c2a17a679..f1e0ba883d0 100644 --- a/core/js/core.json +++ b/core/js/core.json @@ -14,6 +14,7 @@ "jquery.ocdialog.js", "oc-dialogs.js", "js.js", + "share.js", "octemplate.js", "eventsource.js", "config.js", diff --git a/core/js/jquery.ocdialog.js b/core/js/jquery.ocdialog.js index 02cd6ac1466..e2433f5f980 100644 --- a/core/js/jquery.ocdialog.js +++ b/core/js/jquery.ocdialog.js @@ -67,8 +67,8 @@ self.parent = self.$dialog.parent().length > 0 ? self.$dialog.parent() : $('body'); var pos = self.parent.position(); self.$dialog.css({ - left: pos.left + (self.parent.width() - self.$dialog.outerWidth())/2, - top: pos.top + (self.parent.height() - self.$dialog.outerHeight())/2 + left: pos.left + ($(window).innerWidth() - self.$dialog.outerWidth())/2, + top: pos.top + ($(window).innerHeight() - self.$dialog.outerHeight())/2 }); }); @@ -160,10 +160,16 @@ } this.parent = this.$dialog.parent().length > 0 ? this.$dialog.parent() : $('body'); content_height = Math.min(content_height, this.parent.height()-20); - this.element.css({ - height: content_height + 'px', - width: this.$dialog.innerWidth()-20 + 'px' - }); + if (content_height> 0) { + this.element.css({ + height: content_height + 'px', + width: this.$dialog.innerWidth()-20 + 'px' + }); + } else { + this.element.css({ + width : this.$dialog.innerWidth() - 20 + 'px' + }); + } }, _createOverlay: function() { if(!this.options.modal) { diff --git a/core/js/js.js b/core/js/js.js index 27bc3c651e3..38b97590430 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1319,6 +1319,114 @@ OC.Util = { }; /** + * Utility class for the history API, + * includes fallback to using the URL hash when + * the browser doesn't support the history API. + */ +OC.Util.History = { + _handlers: [], + + /** + * Push the current URL parameters to the history stack + * and change the visible URL. + * Note: this includes a workaround for IE8/IE9 that uses + * the hash part instead of the search part. + * + * @param params to append to the URL, can be either a string + * or a map + */ + pushState: function(params) { + var strParams; + if (typeof(params) === 'string') { + strParams = params; + } + else { + strParams = OC.buildQueryString(params); + } + if (window.history.pushState) { + var url = location.pathname + '?' + strParams; + window.history.pushState(params, '', url); + } + // use URL hash for IE8 + else { + window.location.hash = '?' + strParams; + // inhibit next onhashchange that just added itself + // to the event queue + this._cancelPop = true; + } + }, + + /** + * Add a popstate handler + * + * @param handler function + */ + addOnPopStateHandler: function(handler) { + this._handlers.push(handler); + }, + + /** + * Parse a query string from the hash part of the URL. + * (workaround for IE8 / IE9) + */ + _parseHashQuery: function() { + var hash = window.location.hash, + pos = hash.indexOf('?'); + if (pos >= 0) { + return hash.substr(pos + 1); + } + return ''; + }, + + _decodeQuery: function(query) { + return query.replace(/\+/g, ' '); + }, + + /** + * Parse the query/search part of the URL. + * Also try and parse it from the URL hash (for IE8) + * + * @return map of parameters + */ + parseUrlQuery: function() { + var query = this._parseHashQuery(), + params; + // try and parse from URL hash first + if (query) { + params = OC.parseQueryString(this._decodeQuery(query)); + } + // else read from query attributes + if (!params) { + params = OC.parseQueryString(this._decodeQuery(location.search)); + } + return params || {}; + }, + + _onPopState: function(e) { + if (this._cancelPop) { + this._cancelPop = false; + return; + } + var params; + if (!this._handlers.length) { + return; + } + params = (e && e.state) || this.parseUrlQuery() || {}; + for (var i = 0; i < this._handlers.length; i++) { + this._handlers[i](params); + } + } +}; + +// fallback to hashchange when no history support +if (window.history.pushState) { + window.onpopstate = _.bind(OC.Util.History._onPopState, OC.Util.History); +} +else { + $(window).on('hashchange', _.bind(OC.Util.History._onPopState, OC.Util.History)); +} + +/** * Get a variable by name * @param {string} name * @return {*} @@ -1368,6 +1476,11 @@ OC.set=function(name, value) { })(); /** + * Namespace for apps + */ +window.OCA = {}; + +/** * select a range in an input field * @link http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area * @param {type} start diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js index 11833f12e2d..54b9442af27 100644 --- a/core/js/oc-dialogs.js +++ b/core/js/oc-dialogs.js @@ -19,7 +19,7 @@ * */ -/* global OC, t, alert */ +/* global OC, t, alert, $ */ /** * this class to ease the usage of jquery dialogs @@ -62,6 +62,65 @@ var OCdialogs = { this.message(text, title, 'notice', OCdialogs.YES_NO_BUTTONS, callback, modal); }, /** + * displays prompt dialog + * @param text content of dialog + * @param title dialog title + * @param callback which will be triggered when user presses YES or NO + * (true or false would be passed to callback respectively) + * @param modal make the dialog modal + * @param name name of the input field + * @param password whether the input should be a password input + */ + prompt: function (text, title, callback, modal, name, password) { + $.when(this._getMessageTemplate()).then(function ($tmpl) { + var dialogName = 'oc-dialog-' + OCdialogs.dialogsCounter + '-content'; + var dialogId = '#' + dialogName; + var $dlg = $tmpl.octemplate({ + dialog_name: dialogName, + title : title, + message : text, + type : 'notice' + }); + var input = $('<input/>'); + input.attr('type', password ? 'password' : 'text').attr('id', dialogName + '-input'); + var label = $('<label/>').attr('for', dialogName + '-input').text(name + ': '); + $dlg.append(label); + $dlg.append(input); + if (modal === undefined) { + modal = false; + } + $('body').append($dlg); + var buttonlist = [ + { + text : t('core', 'Yes'), + click : function () { + if (callback !== undefined) { + callback(true, input.val()); + } + $(dialogId).ocdialog('close'); + }, + defaultButton: true + }, + { + text : t('core', 'No'), + click: function () { + if (callback !== undefined) { + callback(false, input.val()); + } + $(dialogId).ocdialog('close'); + } + } + ]; + + $(dialogId).ocdialog({ + closeOnEscape: true, + modal : modal, + buttons : buttonlist + }); + OCdialogs.dialogsCounter++; + }); + }, + /** * show a file picker to pick a file from * @param title dialog title * @param callback which will be triggered when user presses Choose @@ -292,7 +351,7 @@ var OCdialogs = { conflict.find('.filename').text(original.name); conflict.find('.original .size').text(humanFileSize(original.size)); - conflict.find('.original .mtime').text(formatDate(original.mtime*1000)); + conflict.find('.original .mtime').text(formatDate(original.mtime)); // ie sucks if (replacement.size && replacement.lastModifiedDate) { conflict.find('.replacement .size').text(humanFileSize(replacement.size)); @@ -315,9 +374,9 @@ var OCdialogs = { //set more recent mtime bold // ie sucks - if (replacement.lastModifiedDate && replacement.lastModifiedDate.getTime() > original.mtime*1000) { + if (replacement.lastModifiedDate && replacement.lastModifiedDate.getTime() > original.mtime) { conflict.find('.replacement .mtime').css('font-weight', 'bold'); - } else if (replacement.lastModifiedDate && replacement.lastModifiedDate.getTime() < original.mtime*1000) { + } else if (replacement.lastModifiedDate && replacement.lastModifiedDate.getTime() < original.mtime) { conflict.find('.original .mtime').css('font-weight', 'bold'); } else { //TODO add to same mtime collection? diff --git a/core/js/share.js b/core/js/share.js index 2813570f718..d013f257579 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -136,7 +136,21 @@ OC.Share={ return data; }, - share:function(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, callback) { + share:function(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, expirationDate, callback) { + // Add a fallback for old share() calls without expirationDate. + // We should remove this in a later version, + // after the Apps have been updated. + if (typeof callback === 'undefined' && + typeof expirationDate === 'function') { + callback = expirationDate; + expirationDate = ''; + console.warn( + "Call to 'OC.Share.share()' with too few arguments. " + + "'expirationDate' was assumed to be 'callback'. " + + "Please revisit the call and fix the list of arguments." + ); + } + $.post(OC.filePath('core', 'ajax', 'share.php'), { action: 'share', @@ -145,7 +159,8 @@ OC.Share={ shareType: shareType, shareWith: shareWith, permissions: permissions, - itemSourceName: itemSourceName + itemSourceName: itemSourceName, + expirationDate: expirationDate }, function (result) { if (result && result.status === 'success') { if (callback) { @@ -219,11 +234,22 @@ OC.Share={ html += '<div id="link">'; html += '<input type="checkbox" name="linkCheckbox" id="linkCheckbox" value="1" /><label for="linkCheckbox">'+t('core', 'Share link')+'</label>'; html += '<br />'; + + var defaultExpireMessage = ''; + if ((itemType === 'folder' || itemType === 'file') && oc_appconfig.core.defaultExpireDateEnabled === 'yes') { + if (oc_appconfig.core.defaultExpireDateEnforced === 'yes') { + defaultExpireMessage = t('core', 'The public link will expire no later than {days} days after it is created', {'days': oc_appconfig.core.defaultExpireDate}) + '<br/>'; + } else { + defaultExpireMessage = t('core', 'By default the public link will expire after {days} days', {'days': oc_appconfig.core.defaultExpireDate}) + '<br/>'; + } + } + html += '<input id="linkText" type="text" readonly="readonly" />'; html += '<input type="checkbox" name="showPassword" id="showPassword" value="1" style="display:none;" /><label for="showPassword" style="display:none;">'+t('core', 'Password protect')+'</label>'; html += '<div id="linkPass">'; - html += '<input id="linkPassText" type="password" placeholder="'+t('core', 'Password')+'" />'; + html += '<input id="linkPassText" type="password" placeholder="'+t('core', 'Choose a password for the public link')+'" />'; html += '</div>'; + if (itemType === 'folder' && (possiblePermissions & OC.PERMISSION_CREATE) && publicUploadEnabled === 'yes') { html += '<div id="allowPublicUploadWrapper" style="display:none;">'; html += '<input type="checkbox" value="1" name="allowPublicUpload" id="sharingDialogAllowPublicUpload"' + ((allowPublicUploadStatus) ? 'checked="checked"' : '') + ' />'; @@ -239,6 +265,7 @@ OC.Share={ html += '<div id="expiration">'; html += '<input type="checkbox" name="expirationCheckbox" id="expirationCheckbox" value="1" /><label for="expirationCheckbox">'+t('core', 'Set expiration date')+'</label>'; html += '<input id="expirationDate" type="text" placeholder="'+t('core', 'Expiration date')+'" style="display:none; width:90%;" />'; + html += '<div id="defaultExpireMessage">'+defaultExpireMessage+'</div>'; html += '</div>'; dropDownEl = $(html); dropDownEl = dropDownEl.appendTo(appendTo); @@ -291,6 +318,10 @@ OC.Share={ var itemType = $('#dropdown').data('item-type'); var itemSource = $('#dropdown').data('item-source'); var itemSourceName = $('#dropdown').data('item-source-name'); + var expirationDate = ''; + if ( $('#expirationCheckbox').is(':checked') === true ) { + expirationDate = $( "#expirationDate" ).val(); + } var shareType = selected.item.value.shareType; var shareWith = selected.item.value.shareWith; $(this).val(shareWith); @@ -310,7 +341,7 @@ OC.Share={ permissions = permissions | OC.PERMISSION_SHARE; } - OC.Share.share(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, function() { + OC.Share.share(itemType, itemSource, shareType, shareWith, permissions, itemSourceName, expirationDate, function() { OC.Share.addShareWith(shareType, shareWith, selected.item.label, permissions, possiblePermissions); $('#shareWith').val(''); OC.Share.updateIcon(itemType, itemSource); @@ -347,8 +378,8 @@ OC.Share={ } }) .data("ui-autocomplete")._renderItem = function( ul, item ) { - return $( "<li>" ) - .append( "<a>" + item.displayname + "<br>" + item.email + "</a>" ) + return $('<li>') + .append('<a>' + escapeHTML(item.displayname) + "<br>" + escapeHTML(item.email) + '</a>' ) .appendTo( ul ); }; } @@ -420,7 +451,7 @@ OC.Share={ } var html = '<li style="clear: both;" data-share-type="'+escapeHTML(shareType)+'" data-share-with="'+escapeHTML(shareWith)+'" title="' + escapeHTML(shareWith) + '">'; var showCrudsButton; - html += '<a href="#" class="unshare"><img class="svg" alt="'+t('core', 'Unshare')+'" src="'+OC.imagePath('core', 'actions/delete')+'"/></a>'; + html += '<a href="#" class="unshare"><img class="svg" alt="'+t('core', 'Unshare')+'" title="'+t('core', 'Unshare')+'" src="'+OC.imagePath('core', 'actions/delete')+'"/></a>'; html += '<span class="username">' + escapeHTML(shareWithDisplayName) + '</span>'; var mailNotificationEnabled = $('input:hidden[name=mailNotificationEnabled]').val(); if (mailNotificationEnabled === 'yes') { @@ -433,7 +464,7 @@ OC.Share={ if (possiblePermissions & OC.PERMISSION_CREATE || possiblePermissions & OC.PERMISSION_UPDATE || possiblePermissions & OC.PERMISSION_DELETE) { html += '<label><input type="checkbox" name="edit" class="permissions" '+editChecked+' />'+t('core', 'can edit')+'</label> '; } - showCrudsButton = '<a href="#" class="showCruds"><img class="svg" alt="'+t('core', 'access control')+'" src="'+OC.imagePath('core', 'actions/triangle-s')+'"/></a>'; + showCrudsButton = '<a href="#" class="showCruds"><img class="svg" alt="'+t('core', 'access control')+'" title="'+t('core', 'access control')+'" src="'+OC.imagePath('core', 'actions/triangle-s')+'"/></a>'; html += '<div class="cruds" style="display:none;">'; if (possiblePermissions & OC.PERMISSION_CREATE) { html += '<label><input type="checkbox" name="create" class="permissions" '+createChecked+' data-permissions="'+OC.PERMISSION_CREATE+'" />'+t('core', 'create')+'</label>'; @@ -464,6 +495,10 @@ OC.Share={ showLink:function(token, password, itemSource) { OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = true; $('#linkCheckbox').attr('checked', true); + + //check itemType + var linkSharetype=$('#dropdown').data('item-type'); + if (! token) { //fallback to pre token link var filename = $('tr').filterAttr('data-id', String(itemSource)).data('file'); @@ -477,32 +512,43 @@ OC.Share={ var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service=files&'+type+'='+encodeURIComponent(file); } else { //TODO add path param when showing a link to file in a subfolder of a public link share - var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service=files&t='+token; + var service=''; + if(linkSharetype === 'folder' || linkSharetype === 'file'){ + service='files'; + }else{ + service=linkSharetype; + } + + var link = parent.location.protocol+'//'+location.host+OC.linkTo('', 'public.php')+'?service='+service+'&t='+token; + } $('#linkText').val(link); $('#linkText').show('blind'); $('#linkText').css('display','block'); - $('#showPassword').show(); - $('#showPassword+label').show(); + if (oc_appconfig.core.enforcePasswordForPublicLink === false || password === null) { + $('#showPassword').show(); + $('#showPassword+label').show(); + } if (password != null) { $('#linkPass').show('blind'); $('#showPassword').attr('checked', true); $('#linkPassText').attr('placeholder', '**********'); } $('#expiration').show(); + $('#defaultExpireMessage').show(); $('#emailPrivateLink #email').show(); $('#emailPrivateLink #emailButton').show(); $('#allowPublicUploadWrapper').show(); }, hideLink:function() { $('#linkText').hide('blind'); + $('#defaultExpireMessage').hide(); $('#showPassword').hide(); $('#showPassword+label').hide(); - $('#linkPass').hide(); + $('#linkPass').hide('blind'); $('#emailPrivateLink #email').hide(); $('#emailPrivateLink #emailButton').hide(); $('#allowPublicUploadWrapper').hide(); - $('#expirationDate').hide(); }, dirname:function(path) { return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, ''); @@ -628,22 +674,33 @@ $(document).ready(function() { var itemType = $('#dropdown').data('item-type'); var itemSource = $('#dropdown').data('item-source'); var itemSourceName = $('#dropdown').data('item-source-name'); + var expirationDate = ''; + if ($('#expirationCheckbox').is(':checked') === true) { + expirationDate = $( "#expirationDate" ).val(); + } if (this.checked) { // Create a link - OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, itemSourceName, function(data) { - OC.Share.showLink(data.token, null, itemSource); - OC.Share.updateIcon(itemType, itemSource); - }); + if (oc_appconfig.core.enforcePasswordForPublicLink === false) { + OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', OC.PERMISSION_READ, itemSourceName, expirationDate, function(data) { + OC.Share.showLink(data.token, null, itemSource); + OC.Share.updateIcon(itemType, itemSource); + }); + } else { + $('#linkPass').toggle('blind'); + $('#linkPassText').focus(); + } } else { // Delete private link - OC.Share.unshare(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', function() { - OC.Share.hideLink(); - OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = false; - OC.Share.updateIcon(itemType, itemSource); - if (typeof OC.Share.statuses[itemSource] === 'undefined') { - $('#expiration').hide('blind'); - } - }); + OC.Share.hideLink(); + if ($('#linkText').val() !== '') { + OC.Share.unshare(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', function() { + OC.Share.itemShares[OC.Share.SHARE_TYPE_LINK] = false; + OC.Share.updateIcon(itemType, itemSource); + if (typeof OC.Share.statuses[itemSource] === 'undefined') { + $('#expiration').hide('blind'); + } + }); + } } }); @@ -660,6 +717,10 @@ $(document).ready(function() { var itemType = $('#dropdown').data('item-type'); var itemSource = $('#dropdown').data('item-source'); var itemSourceName = $('#dropdown').data('item-source-name'); + var expirationDate = ''; + if ($('#expirationCheckbox').is(':checked') === true) { + expirationDate = $( "#expirationDate" ).val(); + } var permissions = 0; // Calculate permissions @@ -670,7 +731,7 @@ $(document).ready(function() { } // Update the share information - OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', permissions, itemSourceName, function(data) { + OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, '', permissions, itemSourceName, expirationDate, function(data) { }); }); @@ -715,11 +776,16 @@ $(document).ready(function() { permissions = OC.PERMISSION_READ; } - OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $('#linkPassText').val(), permissions, itemSourceName, function() { - console.log("password set to: '" + linkPassText.val() +"' by event: " + event.type); + OC.Share.share(itemType, itemSource, OC.Share.SHARE_TYPE_LINK, $('#linkPassText').val(), permissions, itemSourceName, function(data) { linkPassText.val(''); linkPassText.attr('placeholder', t('core', 'Password protected')); + + if (oc_appconfig.core.enforcePasswordForPublicLink) { + OC.Share.showLink(data.token, "password set", itemSource); + OC.Share.updateIcon(itemType, itemSource); + } }); + } }); @@ -734,6 +800,9 @@ $(document).ready(function() { OC.dialogs.alert(t('core', 'Error unsetting expiration date'), t('core', 'Error')); } $('#expirationDate').hide('blind'); + if (oc_appconfig.core.defaultExpireDateEnforced === 'no') { + $('#defaultExpireMessage'). show('blind'); + } }); } }); @@ -756,6 +825,10 @@ $(document).ready(function() { expirationDateField.tipsy({gravity: 'n', fade: true}); expirationDateField.tipsy('show'); expirationDateField.addClass('error'); + } else { + if (oc_appconfig.core.defaultExpireDateEnforced === 'no') { + $('#defaultExpireMessage'). hide('blind'); + } } }); }); diff --git a/core/js/tests/specHelper.js b/core/js/tests/specHelper.js index d86cd81cda8..b9be9188a4e 100644 --- a/core/js/tests/specHelper.js +++ b/core/js/tests/specHelper.js @@ -63,6 +63,9 @@ window.oc_config = { session_lifetime: 600 * 1000, session_keepalive: false }; +window.oc_appconfig = { + core: {} +}; window.oc_defaults = {}; // global setup for all tests diff --git a/core/js/tests/specs/shareSpec.js b/core/js/tests/specs/shareSpec.js new file mode 100644 index 00000000000..a487b71fdbb --- /dev/null +++ b/core/js/tests/specs/shareSpec.js @@ -0,0 +1,97 @@ +/** +* ownCloud +* +* @author Vincent Petry +* @copyright 2014 Vincent Petry <pvince81@owncloud.com> +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/* global oc_appconfig */ +describe('OC.Share tests', function() { + describe('dropdown', function() { + var $container; + var oldAppConfig; + var loadItemStub; + var autocompleteStub; + beforeEach(function() { + $('#testArea').append($('<div id="shareContainer"></div>')); + $container = $('#shareContainer'); + /* jshint camelcase:false */ + oldAppConfig = oc_appconfig.core; + loadItemStub = sinon.stub(OC.Share, 'loadItem'); + + loadItemStub.returns({ + reshare: [], + shares: [] + }); + + autocompleteStub = sinon.stub($.fn, 'autocomplete', function() { + // dummy container with the expected attributes + var $el = $('<div></div>').data('ui-autocomplete', {}); + return $el; + }); + }); + afterEach(function() { + /* jshint camelcase:false */ + oc_appconfig.core = oldAppConfig; + loadItemStub.restore(); + + autocompleteStub.restore(); + }); + it('calls loadItem with the correct arguments', function() { + OC.Share.showDropDown( + 'file', + 123, + $container, + 'http://localhost/dummylink', + 31, + 'shared_file_name.txt' + ); + expect(loadItemStub.calledOnce).toEqual(true); + expect(loadItemStub.calledWith('file', 123)).toEqual(true); + }); + it('shows the dropdown with default values', function() { + var $el; + OC.Share.showDropDown( + 'file', + 123, + $container, + 'http://localhost/dummylink', + 31, + 'shared_file_name.txt' + ); + $el = $container.find('#dropdown'); + expect($el.length).toEqual(1); + expect($el.attr('data-item-type')).toEqual('file'); + expect($el.attr('data-item-source')).toEqual('123'); + // TODO: expect that other parts are rendered correctly + }); + it('shows default expiration date when set', function() { + oc_appconfig.core.defaultExpireDateEnabled = "yes"; + oc_appconfig.core.defaultExpireDate = ''; + // TODO: expect that default date was set + }); + it('shows default expiration date is set but disabled', function() { + oc_appconfig.core.defaultExpireDateEnabled = "no"; + oc_appconfig.core.defaultExpireDate = ''; + // TODO: expect that default date was NOT set + }); + // TODO: test password field visibility (whenever enforced or not) + // TODO: check link share field visibility based on whether it is allowed + // TODO: check public upload visibility based on config + }); +}); + diff --git a/core/js/visitortimezone.js b/core/js/visitortimezone.js index ee0105c783d..d9b63a10879 100644 --- a/core/js/visitortimezone.js +++ b/core/js/visitortimezone.js @@ -1,4 +1,10 @@ $(document).ready(function () { var visitortimezone = (-new Date().getTimezoneOffset() / 60); $('#timezone-offset').val(visitortimezone); + + // only enable the submit button once we are sure that the timezone is set + var $loginForm = $('form[name="login"]'); + if ($loginForm.length) { + $loginForm.find('input#submit').prop('disabled', false); + } }); |