commit 3de40256bff662f8e9ffb1e963263f714c449450
parent 8a0081c84e6ae64d67fcec09baebf1da10847584
Author: Dan Stillman <dstillman@zotero.org>
Date: Thu, 23 Jun 2016 01:30:14 -0400
Restore drag-and-drop Quick Copy
Diffstat:
4 files changed, 99 insertions(+), 23 deletions(-)
diff --git a/chrome/content/zotero/xpcom/itemTreeView.js b/chrome/content/zotero/xpcom/itemTreeView.js
@@ -2532,8 +2532,6 @@ Zotero.ItemTreeView.prototype.onDragStart = function (event) {
}
// Get Quick Copy format for current URL
-// TODO: Fix this
-/** Currently broken
var url = this._ownerDocument.defaultView.content && this._ownerDocument.defaultView.content.location ?
this._ownerDocument.defaultView.content.location.href : null;
var format = Zotero.QuickCopy.getFormatFromURL(url);
@@ -2572,7 +2570,6 @@ Zotero.ItemTreeView.prototype.onDragStart = function (event) {
Zotero.debug(e);
Components.utils.reportError(e + " with '" + format.id + "'");
}
-*/
};
diff --git a/chrome/content/zotero/xpcom/quickCopy.js b/chrome/content/zotero/xpcom/quickCopy.js
@@ -27,9 +27,18 @@
Zotero.QuickCopy = new function() {
var _siteSettings;
var _formattedNames;
+ var _initialized = false;
this.init = Zotero.Promise.coroutine(function* () {
yield this.loadSiteSettings();
+
+ // Load code for selected export translator ahead of time
+ // (in the background, because it requires translator initialization)
+ setTimeout(_loadOutputFormat, 5000);
+ if (!_initialized) {
+ Zotero.Prefs.registerObserver("export.quickCopy.setting", () => _loadOutputFormat());
+ _initialized = true;
+ }
});
@@ -405,6 +414,22 @@ Zotero.QuickCopy = new function() {
};
+ /**
+ * If an export translator is the selected output format, load its code (which must be done
+ * asynchronously) ahead of time, since drag-and-drop requires synchronous operation
+ */
+ var _loadOutputFormat = Zotero.Promise.coroutine(function* () {
+ var format = Zotero.Prefs.get("export.quickCopy.setting");
+ format = Zotero.QuickCopy.unserializeSetting(format);
+ if (format.mode == 'export') {
+ yield Zotero.Translators.init();
+ let translator = Zotero.Translators.get(format.id);
+ translator.cacheCode = true;
+ yield translator.getCode();
+ }
+ });
+
+
var _loadFormattedNames = Zotero.Promise.coroutine(function* () {
var t = new Date;
Zotero.debug("Loading formatted names for Quick Copy");
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
@@ -1245,15 +1245,22 @@ Zotero.Translate.Base.prototype = {
this.setHandler("done", doneHandler);
this.setHandler("error", errorHandler);
- if(typeof this.translator[0] === "object") {
- // already have a translator object, so use it
- this._loadTranslator(this.translator[0]).then(function() { me._translateTranslatorLoaded() });
- } else {
- // need to get translator first
- let translator = Zotero.Translators.get(this.translator[0]);
- this.translator[0] = translator;
- this._loadTranslator(translator).then(function() { me._translateTranslatorLoaded() });
+ // need to get translator first
+ if (typeof this.translator[0] !== "object") {
+ this.translator[0] = Zotero.Translators.get(this.translator[0]);
+ }
+
+ var loadPromise = this._loadTranslator(this.translator[0]);
+ if (this.noWait) {
+ if (!loadPromise.isResolved()) {
+ return Zotero.Promise.reject(new Error("Load promise is not resolved in noWait mode"));
+ }
+ this._translateTranslatorLoaded();
+ }
+ else {
+ loadPromise.then(() => this._translateTranslatorLoaded());
}
+
return deferred.promise;
},
@@ -1633,7 +1640,7 @@ Zotero.Translate.Base.prototype = {
* @param {Zotero.Translator} translator
* @return {Boolean} Whether the translator could be successfully loaded
*/
- "_loadTranslator":function(translator) {
+ "_loadTranslator": Zotero.Promise.method(function (translator) {
var sandboxLocation = this._getSandboxLocation();
if(!this._sandboxLocation || sandboxLocation !== this._sandboxLocation) {
this._sandboxLocation = sandboxLocation;
@@ -1646,19 +1653,42 @@ Zotero.Translate.Base.prototype = {
this._aborted = false;
this.saveQueue = [];
- var me = this;
- return translator.getCode().then(function(code) {
+ var parse = function(code) {
Zotero.debug("Translate: Parsing code for " + translator.label + " "
+ "(" + translator.translatorID + ", " + translator.lastUpdated + ")", 4);
- me._sandboxManager.eval("var exports = {}, ZOTERO_TRANSLATOR_INFO = "+code,
- ["detect"+me._entryFunctionSuffix, "do"+me._entryFunctionSuffix, "exports",
- "ZOTERO_TRANSLATOR_INFO"],
- (translator.file ? translator.file.path : translator.label));
- me._translatorInfo = me._sandboxManager.sandbox.ZOTERO_TRANSLATOR_INFO;
- }).catch(function(e) {
- me.complete(false, e);
- });
- },
+ this._sandboxManager.eval(
+ "var exports = {}, ZOTERO_TRANSLATOR_INFO = " + code,
+ [
+ "detect" + this._entryFunctionSuffix,
+ "do" + this._entryFunctionSuffix,
+ "exports",
+ "ZOTERO_TRANSLATOR_INFO"
+ ],
+ (translator.file ? translator.file.path : translator.label)
+ );
+ this._translatorInfo = this._sandboxManager.sandbox.ZOTERO_TRANSLATOR_INFO;
+ }.bind(this);
+
+ if (this.noWait) {
+ try {
+ let codePromise = translator.getCode();
+ if (!codePromise.isResolved()) {
+ throw new Error("Code promise is not resolved in noWait mode");
+ }
+ parse(codePromise.value());
+ }
+ catch (e) {
+ this.complete(false, e);
+ }
+ }
+ else {
+ return translator.getCode()
+ .then(parse)
+ .catch(function(e) {
+ this.complete(false, e);
+ }.bind(this));
+ }
+ }),
/**
* Generates a sandbox for scraping/scraper detection
diff --git a/test/tests/quickCopyTest.js b/test/tests/quickCopyTest.js
@@ -33,4 +33,28 @@ describe("Zotero.QuickCopy", function() {
assert.deepEqual(Zotero.QuickCopy.getFormatFromURL('chrome://zotero/content/tab.xul'), quickCopyPref);
})
})
+
+ describe("#getContentFromItems()", function () {
+ it("should generate BibTeX", function* () {
+ var item = yield createDataObject('item');
+ var content = "";
+ var worked = false;
+
+ var format = 'export=9cb70025-a888-4a29-a210-93ec52da40d4'; // BibTeX
+ Zotero.Prefs.set('export.quickCopy.setting', format);
+ // The translator code is loaded automatically on pref change, but let's not wait for it
+ yield Zotero.QuickCopy.init();
+
+ Zotero.QuickCopy.getContentFromItems(
+ [item],
+ format,
+ (obj, w) => {
+ content = obj.string;
+ worked = w;
+ }
+ );
+ assert.isTrue(worked);
+ assert.isTrue(content.trim().startsWith('@'));
+ });
+ });
})