Switch to using XHR directly, and drop jquery dep.

This commit is contained in:
Ian Gulliver
2014-05-17 16:31:23 +03:00
parent 6615bb88e2
commit 96b17ad6ff
2 changed files with 54 additions and 56 deletions

View File

@@ -44,7 +44,6 @@ Cosmopolite = function(callbacks, urlPrefix, namespace) {
this.subscriptions_ = {}; this.subscriptions_ = {};
var scriptUrls = [ var scriptUrls = [
'https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js',
'/_ah/channel/jsapi', '/_ah/channel/jsapi',
]; ];
this.numScriptsToLoad_ = scriptUrls.length; this.numScriptsToLoad_ = scriptUrls.length;
@@ -214,11 +213,6 @@ Cosmopolite.prototype.onLoad_ = function() {
if (--this.numScriptsToLoad_ > 0) { if (--this.numScriptsToLoad_ > 0) {
return; return;
} }
// jQuery.noConflict() doesn't actually remove window.$ and window.jQuery,
// it just sets them back to undefined. This angers QUnit's globals
// detection. goog.appengine.Channel doesn't even provide a noConflict()
// equivalent.
this.$ = jQuery.noConflict(true);
if (this.shutdown_) { if (this.shutdown_) {
// Shutdown during startup // Shutdown during startup
return; return;
@@ -318,53 +312,60 @@ Cosmopolite.prototype.sendRPCs_ = function(commands, delay) {
if (this.namespace_ + ':google_user_id' in localStorage) { if (this.namespace_ + ':google_user_id' in localStorage) {
request['google_user_id'] = localStorage[this.namespace_ + ':google_user_id']; request['google_user_id'] = localStorage[this.namespace_ + ':google_user_id'];
} }
this.$.ajax({
url: this.urlPrefix_ + '/api', var xhr = new XMLHttpRequest();
type: 'post', xhr.responseType = 'json';
data: JSON.stringify(request),
dataType: 'json', var retryAfterDelay = function() {
context: this, var intDelay =
}) xhr.getResponseHeader('Retry-After') ||
.done(function(data, stat, xhr) { Math.min(32, Math.max(2, delay || 2));
if ('google_user_id' in data) { console.log(
localStorage[this.namespace_ + ':google_user_id'] = this.loggingPrefix_(),
data['google_user_id']; 'RPC failed; will retry in ' + intDelay + ' seconds');
var retry = function() {
this.sendRPCs_(commands, Math.pow(intDelay, 2));
}.bind(this);
window.setTimeout(retry, intDelay * 1000);
}.bind(this);
xhr.addEventListener('load', function(e) {
if (xhr.status != 200) {
retryAfterDelay();
return;
}
var data = xhr.response;
if ('google_user_id' in data) {
localStorage[this.namespace_ + ':google_user_id'] =
data['google_user_id'];
}
if ('client_id' in data) {
localStorage[this.namespace_ + ':client_id'] = data['client_id'];
}
if (data['status'] == 'retry') {
// Discard delay
this.sendRPCs_(commands);
return;
}
if (data['status'] != 'ok') {
console.log(this.loggingPrefix_(),
'server returned unknown status:', data['status']);
// TODO(flamingcow): Refresh the page? Show an alert?
return;
}
for (var i = 0; i < data['responses'].length; i++) {
if (commands[i]['onSuccess']) {
commands[i]['onSuccess'].bind(this)(data['responses'][i]);
} }
if ('client_id' in data) { }
localStorage[this.namespace_ + ':client_id'] = data['client_id']; // Handle events that were immediately available as if they came over the
} // channel.
if (data['status'] == 'retry') { data['events'].forEach(this.onServerEvent_, this);
// Discard delay }.bind(this));
this.sendRPCs_(commands);
return; xhr.addEventListener('error', retryAfterDelay);
} xhr.open('POST', this.urlPrefix_ + '/api');
if (data['status'] != 'ok') { xhr.send(JSON.stringify(request));
console.log(this.loggingPrefix_(),
'server returned unknown status:', data['status']);
// TODO(flamingcow): Refresh the page? Show an alert?
return;
}
for (var i = 0; i < data['responses'].length; i++) {
if (commands[i]['onSuccess']) {
commands[i]['onSuccess'].bind(this)(data['responses'][i]);
}
}
// Handle events that were immediately available as if they came over the
// channel.
data['events'].forEach(this.onServerEvent_, this);
})
.fail(function(xhr) {
var intDelay =
xhr.getResponseHeader('Retry-After') ||
Math.min(32, Math.max(2, delay || 2));
console.log(
this.loggingPrefix_(),
'RPC failed; will retry in ' + intDelay + ' seconds');
function retry() {
this.sendRPCs_(commands, Math.pow(intDelay, 2));
}
window.setTimeout(retry.bind(this), intDelay * 1000);
});
}; };
/** /**

View File

@@ -29,10 +29,7 @@ not to verify the behavior of a simulation.
These tests break if you turn on global pollution detection because of at These tests break if you turn on global pollution detection because of at
least: least:
* $, jQuery: jQuery's noConflict() doesn't actually delete $ or jQuery; it * goog: goog.appengine.Channel seems to always be global.
sets them to undefined.
* goog: goog.appengine.Channel doesn't provide any kind of noConflict()
equivalent.
* closure_lm_*: The Channel code has a bug that puts this in globals. * closure_lm_*: The Channel code has a bug that puts this in globals.
*/ */