Recognizes and opens files even without extensions.

Closes #842
Also:
Changes AsyncChannel to be a coroutine.
This commit is contained in:
Adomas Venčkauskas 2015-11-19 20:00:35 +00:00
parent 08cb63f66d
commit 2de0ed7871

View File

@ -1149,17 +1149,13 @@ function AsyncChannel(uri, gen) {
} }
AsyncChannel.prototype = { AsyncChannel.prototype = {
asyncOpen: function (streamListener, context) { asyncOpen: Zotero.Promise.coroutine(function* (streamListener, context) {
if (this.loadGroup) this.loadGroup.addRequest(this, null); if (this.loadGroup) this.loadGroup.addRequest(this, null);
var channel = this; var channel = this;
var resolve; var resolve;
var reject; var reject;
var promise = new Zotero.Promise(function () {
resolve = arguments[0];
reject = arguments[1];
});
var listenerWrapper = { var listenerWrapper = {
onStartRequest: function (request, context) { onStartRequest: function (request, context) {
@ -1194,10 +1190,10 @@ AsyncChannel.prototype = {
uri2.spec = uri2.scheme + '://' + matches[1] + '/' + (matches[2] ? matches[2] : ''); uri2.spec = uri2.scheme + '://' + matches[1] + '/' + (matches[2] ? matches[2] : '');
var data = Zotero.File.getContentsFromURL(uri2.spec); var data = Zotero.File.getContentsFromURL(uri2.spec);
} }
Zotero.Promise.try(function () { try {
return data ? data : Zotero.spawn(channel._generator, channel); if (!data) {
}) data = yield Zotero.spawn(channel._generator, channel)
.then(function (data) { }
if (typeof data == 'string') { if (typeof data == 'string') {
Zotero.debug("AsyncChannel: Got string from generator"); Zotero.debug("AsyncChannel: Got string from generator");
@ -1210,7 +1206,6 @@ AsyncChannel.prototype = {
listenerWrapper.onDataAvailable(this, context, inputStream, 0, data.length); listenerWrapper.onDataAvailable(this, context, inputStream, 0, data.length);
listenerWrapper.onStopRequest(this, context, this.status); listenerWrapper.onStopRequest(this, context, this.status);
return promise;
} }
// If an async input stream is given, pass the data asynchronously to the stream listener // If an async input stream is given, pass the data asynchronously to the stream listener
else if (data instanceof Ci.nsIAsyncInputStream) { else if (data instanceof Ci.nsIAsyncInputStream) {
@ -1219,7 +1214,6 @@ AsyncChannel.prototype = {
var pump = Cc["@mozilla.org/network/input-stream-pump;1"].createInstance(Ci.nsIInputStreamPump); var pump = Cc["@mozilla.org/network/input-stream-pump;1"].createInstance(Ci.nsIInputStreamPump);
pump.init(data, -1, -1, 0, 0, true); pump.init(data, -1, -1, 0, 0, true);
pump.asyncRead(listenerWrapper, context); pump.asyncRead(listenerWrapper, context);
return promise;
} }
else if (data instanceof Ci.nsIFile || data instanceof Ci.nsIURI) { else if (data instanceof Ci.nsIFile || data instanceof Ci.nsIURI) {
if (data instanceof Ci.nsIFile) { if (data instanceof Ci.nsIFile) {
@ -1233,6 +1227,10 @@ AsyncChannel.prototype = {
let uri = data; let uri = data;
uri.QueryInterface(Ci.nsIURL); uri.QueryInterface(Ci.nsIURL);
this.contentType = Zotero.MIME.getMIMETypeFromExtension(uri.fileExtension); this.contentType = Zotero.MIME.getMIMETypeFromExtension(uri.fileExtension);
if (!this.contentType) {
let sample = yield Zotero.File.getSample(data);
this.contentType = Zotero.MIME.getMIMETypeFromData(sample);
}
Components.utils.import("resource://gre/modules/NetUtil.jsm"); Components.utils.import("resource://gre/modules/NetUtil.jsm");
NetUtil.asyncFetch(data, function (inputStream, status) { NetUtil.asyncFetch(data, function (inputStream, status) {
@ -1250,7 +1248,6 @@ AsyncChannel.prototype = {
} }
listenerWrapper.onStopRequest(channel, context, status); listenerWrapper.onStopRequest(channel, context, status);
}); });
return promise;
} }
else if (data === undefined) { else if (data === undefined) {
this.cancel(0x804b0002); // BINDING_ABORTED this.cancel(0x804b0002); // BINDING_ABORTED
@ -1258,25 +1255,22 @@ AsyncChannel.prototype = {
else { else {
throw new Error("Invalid return type (" + typeof data + ") from generator passed to AsyncChannel"); throw new Error("Invalid return type (" + typeof data + ") from generator passed to AsyncChannel");
} }
}.bind(this))
.then(function () {
if (this._isPending) { if (this._isPending) {
Zotero.debug("AsyncChannel request succeeded in " + (new Date - t) + " ms"); Zotero.debug("AsyncChannel request succeeded in " + (new Date - t) + " ms");
channel._isPending = false; channel._isPending = false;
} }
}) } catch (e) {
.catch(function (e) {
Zotero.debug(e, 1); Zotero.debug(e, 1);
if (channel._isPending) { if (channel._isPending) {
streamListener.onStopRequest(channel, context, Components.results.NS_ERROR_FAILURE); streamListener.onStopRequest(channel, context, Components.results.NS_ERROR_FAILURE);
channel._isPending = false; channel._isPending = false;
} }
throw e; throw e;
}) } finally {
.finally(function () {
if (channel.loadGroup) channel.loadGroup.removeRequest(channel, null, 0); if (channel.loadGroup) channel.loadGroup.removeRequest(channel, null, 0);
}); }
}, }),
// nsIRequest // nsIRequest
isPending: function () { isPending: function () {