Compatibility fixes for shared connector code (#1082)

Safari does not support generators yet. Removes coroutines
and removes the requirement for bluebird, which should
improve script injection performance.
This commit is contained in:
Adomas Ven 2016-09-06 02:49:23 +03:00 committed by Dan Stillman
parent f68ee60524
commit 5859dd6956
6 changed files with 79 additions and 50 deletions

View file

@ -84,7 +84,7 @@ Zotero.Connector_Types = new function() {
return ZOTERO_CONFIG.BOOKMARKLET_URL+"images/"+icon;
} else if(Zotero.isFx) {
return "chrome://zotero/skin/"+icon;
} else if(Zotero.isChrome) {
} else if(Zotero.isBrowserExt) {
return chrome.extension.getURL("images/"+icon);
} else if(Zotero.isSafari) {
return safari.extension.baseURI+"images/"+icon;

View file

@ -240,7 +240,7 @@ Zotero.Connector = new function() {
this.callMethod("saveItems", data, callback, tab);
return;
} else if(Zotero.isChrome && !Zotero.isBookmarklet) {
} else if(Zotero.isBrowserExt && !Zotero.isBookmarklet) {
var self = this;
chrome.cookies.getAll({url: tab.url}, function(cookies) {
var cookieHeader = '';

View file

@ -544,7 +544,7 @@ Zotero.Translate.ItemSaver.prototype = {
}
attachment.md5 = hash;
if(Zotero.isChrome && !Zotero.isBookmarklet) {
if(Zotero.isBrowserExt && !Zotero.isBookmarklet) {
// In Chrome, we don't use messaging for Zotero.API.uploadAttachment, since
// we can't pass ArrayBuffers to the background page
Zotero.API.uploadAttachment(attachment, attachmentCallback.bind(this, attachment));

View file

@ -42,7 +42,7 @@ Zotero.Translators = new function() {
this.init = function(translators) {
if(!translators) {
translators = [];
if((Zotero.isChrome || Zotero.isSafari) && localStorage["translatorMetadata"]) {
if((Zotero.isBrowserExt || Zotero.isSafari) && localStorage["translatorMetadata"]) {
try {
translators = JSON.parse(localStorage["translatorMetadata"]);
if(typeof translators !== "object") {
@ -196,7 +196,7 @@ Zotero.Translators = new function() {
if(j === 0) {
converterFunctions.push(null);
} else if(Zotero.isChrome || Zotero.isSafari) {
} else if(Zotero.isBrowserExt || Zotero.isSafari) {
// in Chrome/Safari, the converterFunction needs to be passed as JSON, so
// just push an array with the proper and proxyHosts
converterFunctions.push([properHosts[j-1], proxyHosts[j-1]]);
@ -303,7 +303,7 @@ Zotero.Translators = new function() {
}
// Store
if(Zotero.isChrome || Zotero.isSafari) {
if (Zotero.isBrowserExt || Zotero.isSafari) {
var serialized = JSON.stringify(serializedTranslators);
localStorage["translatorMetadata"] = serialized;
Zotero.debug("Translators: Saved updated translator list ("+serialized.length+" characters)");
@ -374,7 +374,8 @@ Zotero.Translators.CodeGetter.prototype.getCodeFor = function(i) {
const TRANSLATOR_REQUIRED_PROPERTIES = ["translatorID", "translatorType", "label", "creator", "target",
"priority", "lastUpdated"];
var TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport", "code", "runMode"]);
var TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES
.concat(["browserSupport", "code", "runMode", "itemType"]);
var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport"]);
/**
* @class Represents an individual translator

View file

@ -373,7 +373,12 @@ Zotero.Translate.Sandbox = {
var translator = translation.translator[0];
translator = typeof translator === "object" ? translator : Zotero.Translators.get(translator);
translation._loadTranslator(translator)
// Zotero.Translators.get returns a value in the client and a promise in connectors
// so we normalize the value to a promise here
Zotero.Promise.resolve(translator)
.then(function(translator) {
return translation._loadTranslator(translator)
})
.then(function() {
if(Zotero.isFx && !Zotero.isBookmarklet) {
// do same origin check
@ -400,7 +405,7 @@ Zotero.Translate.Sandbox = {
})
.then(function () {
setDefaultHandlers(translate, translation);
sandbox = translation._sandboxManager.sandbox;
var sandbox = translation._sandboxManager.sandbox;
if(!Zotero.Utilities.isEmpty(sandbox.exports)) {
sandbox.exports.Zotero = sandbox.Zotero;
sandbox = sandbox.exports;
@ -679,7 +684,7 @@ Zotero.Translate.Sandbox = {
// refuse to save very long tags
if(item.tags) {
for(var i=0; i<item.tags.length; i++) {
var tag = item.tags[i];
var tag = item.tags[i],
tagString = typeof tag === "string" ? tag :
typeof tag === "object" ? (tag.tag || tag.name) : null;
if(tagString && tagString.length > 255) {
@ -1111,7 +1116,9 @@ Zotero.Translate.Base.prototype = {
// if detection returns immediately, return found translators
var me = this;
return potentialTranslators.spread(function(allPotentialTranslators, properToProxyFunctions) {
return potentialTranslators.then(function(result) {
var allPotentialTranslators = result[0];
var properToProxyFunctions = result[1];
me._potentialTranslators = [];
me._foundTranslators = [];
@ -1266,25 +1273,35 @@ Zotero.Translate.Base.prototype = {
/**
* Called when translator has been retrieved and loaded
*/
"_translateTranslatorLoaded": Zotero.Promise.coroutine(function* () {
"_translateTranslatorLoaded": Zotero.Promise.method(function() {
// set display options to default if they don't exist
if(!this._displayOptions) this._displayOptions = this._translatorInfo.displayOptions || {};
yield this._prepareTranslation();
Zotero.debug("Translate: Beginning translation with "+this.translator[0].label);
this.incrementAsyncProcesses("Zotero.Translate#translate()");
// translate
try {
Function.prototype.apply.call(this._sandboxManager.sandbox["do"+this._entryFunctionSuffix], null, this._getParameters());
} catch(e) {
this.complete(false, e);
return false;
var loadPromise = this._prepareTranslation();
if (this.noWait) {
if (!loadPromise.isResolved()) {
throw new Error("Load promise is not resolved in noWait mode");
}
rest.apply(this, arguments);
} else {
return loadPromise.then(() => rest.apply(this, arguments))
}
this.decrementAsyncProcesses("Zotero.Translate#translate()");
function rest() {
Zotero.debug("Translate: Beginning translation with " + this.translator[0].label);
this.incrementAsyncProcesses("Zotero.Translate#translate()");
// translate
try {
Function.prototype.apply.call(this._sandboxManager.sandbox["do" + this._entryFunctionSuffix], null, this._getParameters());
} catch (e) {
this.complete(false, e);
return false;
}
this.decrementAsyncProcesses("Zotero.Translate#translate()");
}
}),
/**
@ -1596,13 +1613,12 @@ Zotero.Translate.Base.prototype = {
let lab = this._potentialTranslators[0].label;
this._loadTranslator(this._potentialTranslators[0])
.bind(this)
.then(function() {
return this._detectTranslatorLoaded();
})
}.bind(this))
.catch(function (e) {
this.complete(false, e);
});
}.bind(this));
},
/**
@ -2309,7 +2325,7 @@ Zotero.Translate.Export.prototype.getTranslators = function() {
/**
* Does the actual export, after code has been loaded and parsed
*/
Zotero.Translate.Export.prototype._prepareTranslation = Zotero.Promise.coroutine(function* () {
Zotero.Translate.Export.prototype._prepareTranslation = Zotero.Promise.method(function () {
this._progress = undefined;
// initialize ItemGetter
@ -2320,6 +2336,7 @@ Zotero.Translate.Export.prototype._prepareTranslation = Zotero.Promise.coroutine
var configOptions = this._translatorInfo.configOptions || {},
getCollections = configOptions.getCollections || false;
var loadPromise = Zotero.Promise.resolve();
switch (this._export.type) {
case 'collection':
this._itemGetter.setCollection(this._export.collection, getCollections);
@ -2328,7 +2345,7 @@ Zotero.Translate.Export.prototype._prepareTranslation = Zotero.Promise.coroutine
this._itemGetter.setItems(this._export.items);
break;
case 'library':
yield this._itemGetter.setAll(this._export.id, getCollections);
loadPromise = this._itemGetter.setAll(this._export.id, getCollections);
break;
default:
throw new Error('No export set up');
@ -2336,27 +2353,38 @@ Zotero.Translate.Export.prototype._prepareTranslation = Zotero.Promise.coroutine
}
delete this._export;
// export file data, if requested
if(this._displayOptions["exportFileData"]) {
this.location = this._itemGetter.exportFiles(this.location, this.translator[0].target);
}
// initialize IO
// this is currently hackish since we pass null callbacks to the init function (they have
// callbacks to be consistent with import, but they are synchronous, so we ignore them)
if(!this.location) {
this._io = new Zotero.Translate.IO.String(null, this.path ? this.path : "", this._sandboxManager);
this._io.init(configOptions["dataMode"], function() {});
} else if(!Zotero.Translate.IO.Write) {
throw new Error("Writing to files is not supported in this build of Zotero.");
if (this.noWait) {
if (!loadPromise.isResolved()) {
throw new Error("Load promise is not resolved in noWait mode");
}
rest.apply(this, arguments);
} else {
this._io = new Zotero.Translate.IO.Write(this.location);
this._io.init(configOptions["dataMode"],
this._displayOptions["exportCharset"] ? this._displayOptions["exportCharset"] : null,
function() {});
return loadPromise.then(() => rest.apply(this, arguments))
}
this._sandboxManager.importObject(this._io);
function rest() {
// export file data, if requested
if(this._displayOptions["exportFileData"]) {
this.location = this._itemGetter.exportFiles(this.location, this.translator[0].target);
}
// initialize IO
// this is currently hackish since we pass null callbacks to the init function (they have
// callbacks to be consistent with import, but they are synchronous, so we ignore them)
if(!this.location) {
this._io = new Zotero.Translate.IO.String(null, this.path ? this.path : "", this._sandboxManager);
this._io.init(configOptions["dataMode"], function() {});
} else if(!Zotero.Translate.IO.Write) {
throw new Error("Writing to files is not supported in this build of Zotero.");
} else {
this._io = new Zotero.Translate.IO.Write(this.location);
this._io.init(configOptions["dataMode"],
this._displayOptions["exportCharset"] ? this._displayOptions["exportCharset"] : null,
function() {});
}
this._sandboxManager.importObject(this._io);
}
});
/**

View file

@ -29,10 +29,10 @@ var TRANSLATOR_REQUIRED_PROPERTIES = ["translatorID", "translatorType", "label",
// Properties that are preserved if present
var TRANSLATOR_OPTIONAL_PROPERTIES = ["browserSupport", "minVersion", "maxVersion",
"inRepository", "configOptions", "displayOptions",
"hiddenPrefs"];
"hiddenPrefs", "itemType"];
// Properties that are passed from background to inject page in connector
var TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.
concat(["browserSupport", "code", "runMode"]);
concat(["browserSupport", "code", "runMode", "itemType"]);
// Properties that are saved in connector if set but not required
var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport"]);