commit 5859dd6956f278d0305fc821f9fe65b4edb7fefa
parent f68ee60524e6e20686c63895c481754bede772d6
Author: Adomas Ven <adomas.ven@gmail.com>
Date: Tue, 6 Sep 2016 02:49:23 +0300
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.
Diffstat:
6 files changed, 79 insertions(+), 50 deletions(-)
diff --git a/chrome/content/zotero/xpcom/connector/cachedTypes.js b/chrome/content/zotero/xpcom/connector/cachedTypes.js
@@ -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;
diff --git a/chrome/content/zotero/xpcom/connector/connector.js b/chrome/content/zotero/xpcom/connector/connector.js
@@ -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 = '';
diff --git a/chrome/content/zotero/xpcom/connector/translate_item.js b/chrome/content/zotero/xpcom/connector/translate_item.js
@@ -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));
diff --git a/chrome/content/zotero/xpcom/connector/translator.js b/chrome/content/zotero/xpcom/connector/translator.js
@@ -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
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
@@ -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);
+ }
});
/**
diff --git a/chrome/content/zotero/xpcom/translation/translator.js b/chrome/content/zotero/xpcom/translation/translator.js
@@ -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"]);