diff --git a/r2/r2/public/static/js/login.js b/r2/r2/public/static/js/login.js index f9f0be478..fd0a176ee 100644 --- a/r2/r2/public/static/js/login.js +++ b/r2/r2/public/static/js/login.js @@ -1,5 +1,5 @@ r.login = { - post: function(form, action, callback) { + post: function(form, action) { if (r.config.cnameframe && !r.config.https_endpoint) { form.$el.unbind() form.$el.submit() @@ -13,15 +13,11 @@ r.login = { if (r.config.currentOrigin == endpoint || $.support.cors) { var params = form.serialize() params.push({name:'api_type', value:'json'}) - $.ajax({ + return $.ajax({ url: apiTarget, type: 'POST', dataType: 'json', data: params, - success: callback, - error: function(xhr, err) { - callback(false, err, xhr) - }, xhrFields: { withCredentials: true } @@ -61,23 +57,25 @@ r.login = { }) .appendTo(postForm) - r.login.hoist.watch(action, function(result) { - if (!r.config.debug) { + var deferred = r.login.hoist.watch(action) + if (!r.config.debug) { + deferred.done(function() { iframe.remove() postForm.remove() - } - callback(result) - }) + }) + } postForm.submit() + return deferred } } } r.login.hoist = { type: 'cookie', - watch: function(name, callback) { - var cookieName = 'hoist_'+name + watch: function(name) { + var cookieName = 'hoist_'+name, + deferred = new $.Deferred var interval = setInterval(function() { data = $.cookie(cookieName) @@ -89,7 +87,7 @@ r.login.hoist = { } $.cookie(cookieName, null, {domain:r.config.cur_domain, path:'/'}) clearInterval(interval) - callback(data) + deferred.resolve(data) } }, 100) } @@ -130,9 +128,10 @@ r.login.ui = { } } - this.popup.showLogin(true, dest && function() { + this.popup.showLogin(true, dest && $.proxy(function() { + this.popup.loginForm.$el.addClass('working') window.location = dest - }) + }, this)) return false } @@ -169,7 +168,7 @@ r.ui.LoginForm.prototype = $.extend(new r.ui.Form(), { }, _submit: function() { - r.login.post(this, 'login', $.proxy(this, 'handleResult')) + return r.login.post(this, 'login') }, _handleResult: function(result) { @@ -178,6 +177,7 @@ r.ui.LoginForm.prototype = $.extend(new r.ui.Form(), { if (this.successCallback) { this.successCallback(result) } else { + this.$el.addClass('working') var base = r.config.extension ? '/.'+r.config.extension : '/', defaultDest = /\/login\/?$/.test($.url().attr('path')) ? base : window.location, destParam = this.$el.find('input[name="dest"]').val() @@ -188,7 +188,7 @@ r.ui.LoginForm.prototype = $.extend(new r.ui.Form(), { } }, - _handleNetError: function(result, err, xhr) { + _handleNetError: function(xhr) { r.ui.Form.prototype._handleNetError.apply(this, arguments) if (xhr.status == 0 && r.config.currentOrigin != r.config.https_endpoint) { $('

').append( @@ -253,7 +253,7 @@ r.ui.RegisterForm.prototype = $.extend(new r.ui.Form(), { }, _submit: function() { - r.login.post(this, 'register', $.proxy(this, 'handleResult')) + return r.login.post(this, 'register') }, _handleResult: r.ui.LoginForm.prototype._handleResult, diff --git a/r2/r2/public/static/js/ui.js b/r2/r2/public/static/js/ui.js index dbb781b50..e5a8fde1e 100644 --- a/r2/r2/public/static/js/ui.js +++ b/r2/r2/public/static/js/ui.js @@ -31,6 +31,32 @@ r.ui.init = function() { r.ui.PermissionEditor.init() } +r.ui.showWorkingDeferred = function(el, deferred) { + var flickerDelay = 200, + key = '_workingCount', + $el = $(el) + + // keep a count of active calls on this element so we can track multiple + // deferreds at the same time. + $el.data(key, ($el.data(key) || 0) + 1) + + // prevent flicker + var flickerTimeout = setTimeout(function() { + $el.addClass('working') + }, flickerDelay) + + deferred.always(function() { + clearTimeout(flickerTimeout) + var count = Math.max(0, $el.data(key) - 1) + $el.data(key, count) + if (count == 0) { + $el.removeClass('working') + } + }) + + return deferred +} + r.ui.refreshListing = function() { var url = $.url(), params = url.param() @@ -52,26 +78,6 @@ r.ui.Form = function(el) { }, this)) } r.ui.Form.prototype = $.extend(new r.ui.Base(), { - workingDelay: 200, - - setWorking: function(isWorking) { - // Delay the initial throbber display to prevent flashes for fast - // operations - if (isWorking) { - if (!this.$el.hasClass('working') && !this._workingTimer) { - this._workingTimer = setTimeout($.proxy(function() { - this.$el.addClass('working') - }, this), this.workingDelay) - } - } else { - if (this._workingTimer) { - clearTimeout(this._workingTimer) - delete this._workingTimer - } - this.$el.removeClass('working') - } - }, - showStatus: function(msg, isError) { this.$el.find('.status') .show() @@ -121,28 +127,23 @@ r.ui.Form.prototype = $.extend(new r.ui.Base(), { submit: function() { this.resetErrors() - this.setWorking(true) - this._submit() + r.ui.showWorkingDeferred(this.$el, this._submit()) + .done($.proxy(this, 'handleResult')) + .fail($.proxy(this, '_handleNetError')) }, _submit: function() {}, - handleResult: function(result, err, xhr) { - if (result) { - this.checkCaptcha(result.json.errors) - this._handleResult(result) - } else { - this.setWorking(false) - this._handleNetError(result, err, xhr) - } + handleResult: function(result) { + this.checkCaptcha(result.json.errors) + this._handleResult(result) }, _handleResult: function(result) { this.showErrors(result.json.errors) - this.setWorking(false) }, - _handleNetError: function(result, err, xhr) { + _handleNetError: function(xhr) { this.showStatus(r.strings('an_error_occurred', {status: xhr.status}), true) } })