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:
parent
f68ee60524
commit
5859dd6956
6 changed files with 79 additions and 50 deletions
|
@ -84,7 +84,7 @@ Zotero.Connector_Types = new function() {
|
||||||
return ZOTERO_CONFIG.BOOKMARKLET_URL+"images/"+icon;
|
return ZOTERO_CONFIG.BOOKMARKLET_URL+"images/"+icon;
|
||||||
} else if(Zotero.isFx) {
|
} else if(Zotero.isFx) {
|
||||||
return "chrome://zotero/skin/"+icon;
|
return "chrome://zotero/skin/"+icon;
|
||||||
} else if(Zotero.isChrome) {
|
} else if(Zotero.isBrowserExt) {
|
||||||
return chrome.extension.getURL("images/"+icon);
|
return chrome.extension.getURL("images/"+icon);
|
||||||
} else if(Zotero.isSafari) {
|
} else if(Zotero.isSafari) {
|
||||||
return safari.extension.baseURI+"images/"+icon;
|
return safari.extension.baseURI+"images/"+icon;
|
||||||
|
|
|
@ -240,7 +240,7 @@ Zotero.Connector = new function() {
|
||||||
|
|
||||||
this.callMethod("saveItems", data, callback, tab);
|
this.callMethod("saveItems", data, callback, tab);
|
||||||
return;
|
return;
|
||||||
} else if(Zotero.isChrome && !Zotero.isBookmarklet) {
|
} else if(Zotero.isBrowserExt && !Zotero.isBookmarklet) {
|
||||||
var self = this;
|
var self = this;
|
||||||
chrome.cookies.getAll({url: tab.url}, function(cookies) {
|
chrome.cookies.getAll({url: tab.url}, function(cookies) {
|
||||||
var cookieHeader = '';
|
var cookieHeader = '';
|
||||||
|
|
|
@ -544,7 +544,7 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
}
|
}
|
||||||
attachment.md5 = hash;
|
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
|
// In Chrome, we don't use messaging for Zotero.API.uploadAttachment, since
|
||||||
// we can't pass ArrayBuffers to the background page
|
// we can't pass ArrayBuffers to the background page
|
||||||
Zotero.API.uploadAttachment(attachment, attachmentCallback.bind(this, attachment));
|
Zotero.API.uploadAttachment(attachment, attachmentCallback.bind(this, attachment));
|
||||||
|
|
|
@ -42,7 +42,7 @@ Zotero.Translators = new function() {
|
||||||
this.init = function(translators) {
|
this.init = function(translators) {
|
||||||
if(!translators) {
|
if(!translators) {
|
||||||
translators = [];
|
translators = [];
|
||||||
if((Zotero.isChrome || Zotero.isSafari) && localStorage["translatorMetadata"]) {
|
if((Zotero.isBrowserExt || Zotero.isSafari) && localStorage["translatorMetadata"]) {
|
||||||
try {
|
try {
|
||||||
translators = JSON.parse(localStorage["translatorMetadata"]);
|
translators = JSON.parse(localStorage["translatorMetadata"]);
|
||||||
if(typeof translators !== "object") {
|
if(typeof translators !== "object") {
|
||||||
|
@ -196,7 +196,7 @@ Zotero.Translators = new function() {
|
||||||
|
|
||||||
if(j === 0) {
|
if(j === 0) {
|
||||||
converterFunctions.push(null);
|
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
|
// in Chrome/Safari, the converterFunction needs to be passed as JSON, so
|
||||||
// just push an array with the proper and proxyHosts
|
// just push an array with the proper and proxyHosts
|
||||||
converterFunctions.push([properHosts[j-1], proxyHosts[j-1]]);
|
converterFunctions.push([properHosts[j-1], proxyHosts[j-1]]);
|
||||||
|
@ -303,7 +303,7 @@ Zotero.Translators = new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
if(Zotero.isChrome || Zotero.isSafari) {
|
if (Zotero.isBrowserExt || Zotero.isSafari) {
|
||||||
var serialized = JSON.stringify(serializedTranslators);
|
var serialized = JSON.stringify(serializedTranslators);
|
||||||
localStorage["translatorMetadata"] = serialized;
|
localStorage["translatorMetadata"] = serialized;
|
||||||
Zotero.debug("Translators: Saved updated translator list ("+serialized.length+" characters)");
|
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",
|
const TRANSLATOR_REQUIRED_PROPERTIES = ["translatorID", "translatorType", "label", "creator", "target",
|
||||||
"priority", "lastUpdated"];
|
"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"]);
|
var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport"]);
|
||||||
/**
|
/**
|
||||||
* @class Represents an individual translator
|
* @class Represents an individual translator
|
||||||
|
|
|
@ -373,7 +373,12 @@ Zotero.Translate.Sandbox = {
|
||||||
|
|
||||||
var translator = translation.translator[0];
|
var translator = translation.translator[0];
|
||||||
translator = typeof translator === "object" ? translator : Zotero.Translators.get(translator);
|
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() {
|
.then(function() {
|
||||||
if(Zotero.isFx && !Zotero.isBookmarklet) {
|
if(Zotero.isFx && !Zotero.isBookmarklet) {
|
||||||
// do same origin check
|
// do same origin check
|
||||||
|
@ -400,7 +405,7 @@ Zotero.Translate.Sandbox = {
|
||||||
})
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
setDefaultHandlers(translate, translation);
|
setDefaultHandlers(translate, translation);
|
||||||
sandbox = translation._sandboxManager.sandbox;
|
var sandbox = translation._sandboxManager.sandbox;
|
||||||
if(!Zotero.Utilities.isEmpty(sandbox.exports)) {
|
if(!Zotero.Utilities.isEmpty(sandbox.exports)) {
|
||||||
sandbox.exports.Zotero = sandbox.Zotero;
|
sandbox.exports.Zotero = sandbox.Zotero;
|
||||||
sandbox = sandbox.exports;
|
sandbox = sandbox.exports;
|
||||||
|
@ -679,7 +684,7 @@ Zotero.Translate.Sandbox = {
|
||||||
// refuse to save very long tags
|
// refuse to save very long tags
|
||||||
if(item.tags) {
|
if(item.tags) {
|
||||||
for(var i=0; i<item.tags.length; i++) {
|
for(var i=0; i<item.tags.length; i++) {
|
||||||
var tag = item.tags[i];
|
var tag = item.tags[i],
|
||||||
tagString = typeof tag === "string" ? tag :
|
tagString = typeof tag === "string" ? tag :
|
||||||
typeof tag === "object" ? (tag.tag || tag.name) : null;
|
typeof tag === "object" ? (tag.tag || tag.name) : null;
|
||||||
if(tagString && tagString.length > 255) {
|
if(tagString && tagString.length > 255) {
|
||||||
|
@ -1111,7 +1116,9 @@ Zotero.Translate.Base.prototype = {
|
||||||
|
|
||||||
// if detection returns immediately, return found translators
|
// if detection returns immediately, return found translators
|
||||||
var me = this;
|
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._potentialTranslators = [];
|
||||||
me._foundTranslators = [];
|
me._foundTranslators = [];
|
||||||
|
|
||||||
|
@ -1266,25 +1273,35 @@ Zotero.Translate.Base.prototype = {
|
||||||
/**
|
/**
|
||||||
* Called when translator has been retrieved and loaded
|
* 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
|
// set display options to default if they don't exist
|
||||||
if(!this._displayOptions) this._displayOptions = this._translatorInfo.displayOptions || {};
|
if(!this._displayOptions) this._displayOptions = this._translatorInfo.displayOptions || {};
|
||||||
|
|
||||||
yield this._prepareTranslation();
|
var loadPromise = this._prepareTranslation();
|
||||||
|
if (this.noWait) {
|
||||||
Zotero.debug("Translate: Beginning translation with "+this.translator[0].label);
|
if (!loadPromise.isResolved()) {
|
||||||
|
throw new Error("Load promise is not resolved in noWait mode");
|
||||||
this.incrementAsyncProcesses("Zotero.Translate#translate()");
|
}
|
||||||
|
rest.apply(this, arguments);
|
||||||
// translate
|
} else {
|
||||||
try {
|
return loadPromise.then(() => rest.apply(this, arguments))
|
||||||
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()");
|
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;
|
let lab = this._potentialTranslators[0].label;
|
||||||
this._loadTranslator(this._potentialTranslators[0])
|
this._loadTranslator(this._potentialTranslators[0])
|
||||||
.bind(this)
|
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return this._detectTranslatorLoaded();
|
return this._detectTranslatorLoaded();
|
||||||
})
|
}.bind(this))
|
||||||
.catch(function (e) {
|
.catch(function (e) {
|
||||||
this.complete(false, 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
|
* 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;
|
this._progress = undefined;
|
||||||
|
|
||||||
// initialize ItemGetter
|
// initialize ItemGetter
|
||||||
|
@ -2320,6 +2336,7 @@ Zotero.Translate.Export.prototype._prepareTranslation = Zotero.Promise.coroutine
|
||||||
|
|
||||||
var configOptions = this._translatorInfo.configOptions || {},
|
var configOptions = this._translatorInfo.configOptions || {},
|
||||||
getCollections = configOptions.getCollections || false;
|
getCollections = configOptions.getCollections || false;
|
||||||
|
var loadPromise = Zotero.Promise.resolve();
|
||||||
switch (this._export.type) {
|
switch (this._export.type) {
|
||||||
case 'collection':
|
case 'collection':
|
||||||
this._itemGetter.setCollection(this._export.collection, getCollections);
|
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);
|
this._itemGetter.setItems(this._export.items);
|
||||||
break;
|
break;
|
||||||
case 'library':
|
case 'library':
|
||||||
yield this._itemGetter.setAll(this._export.id, getCollections);
|
loadPromise = this._itemGetter.setAll(this._export.id, getCollections);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error('No export set up');
|
throw new Error('No export set up');
|
||||||
|
@ -2336,27 +2353,38 @@ Zotero.Translate.Export.prototype._prepareTranslation = Zotero.Promise.coroutine
|
||||||
}
|
}
|
||||||
delete this._export;
|
delete this._export;
|
||||||
|
|
||||||
// export file data, if requested
|
if (this.noWait) {
|
||||||
if(this._displayOptions["exportFileData"]) {
|
if (!loadPromise.isResolved()) {
|
||||||
this.location = this._itemGetter.exportFiles(this.location, this.translator[0].target);
|
throw new Error("Load promise is not resolved in noWait mode");
|
||||||
}
|
}
|
||||||
|
rest.apply(this, arguments);
|
||||||
// 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 {
|
} else {
|
||||||
this._io = new Zotero.Translate.IO.Write(this.location);
|
return loadPromise.then(() => rest.apply(this, arguments))
|
||||||
this._io.init(configOptions["dataMode"],
|
|
||||||
this._displayOptions["exportCharset"] ? this._displayOptions["exportCharset"] : null,
|
|
||||||
function() {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,10 +29,10 @@ var TRANSLATOR_REQUIRED_PROPERTIES = ["translatorID", "translatorType", "label",
|
||||||
// Properties that are preserved if present
|
// Properties that are preserved if present
|
||||||
var TRANSLATOR_OPTIONAL_PROPERTIES = ["browserSupport", "minVersion", "maxVersion",
|
var TRANSLATOR_OPTIONAL_PROPERTIES = ["browserSupport", "minVersion", "maxVersion",
|
||||||
"inRepository", "configOptions", "displayOptions",
|
"inRepository", "configOptions", "displayOptions",
|
||||||
"hiddenPrefs"];
|
"hiddenPrefs", "itemType"];
|
||||||
// Properties that are passed from background to inject page in connector
|
// Properties that are passed from background to inject page in connector
|
||||||
var TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.
|
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
|
// Properties that are saved in connector if set but not required
|
||||||
var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport"]);
|
var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport"]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue