fx-compat: RemoteTranslate improvements
- Support removeHandler() - Return DB items from translate() when called with libraryID - Don't invoke done until attachments are done Fixes #3084 ("after all" hook still times out, but that happens even if the test is disabled)
This commit is contained in:
parent
096a3c5f2f
commit
b222bbcccb
3 changed files with 64 additions and 17 deletions
|
@ -53,8 +53,8 @@ class RemoteTranslate {
|
|||
_wasSuccess = false;
|
||||
|
||||
constructor() {
|
||||
TranslationManager.add(this._id);
|
||||
TranslationManager.setHandler(this._id, 'done', success => this._wasSuccess = success);
|
||||
TranslationManager.add(this._id, this);
|
||||
TranslationManager.setHandler(this._id, 'done', (_, success) => this._wasSuccess = success);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,7 +86,23 @@ class RemoteTranslate {
|
|||
this._doneHandlers.push(handler);
|
||||
}
|
||||
else {
|
||||
TranslationManager.setHandler(this._id, name, (...args) => handler(this, ...args));
|
||||
TranslationManager.setHandler(this._id, name, handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a handler added by #setHandler().
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} handler
|
||||
*/
|
||||
removeHandler(name, handler) {
|
||||
// 'done' is triggered from translate()
|
||||
if (name == 'done') {
|
||||
this._doneHandlers = this._doneHandlers.filter(h => h !== handler);
|
||||
}
|
||||
else {
|
||||
TranslationManager.removeHandler(this._id, name, handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,10 +157,13 @@ class RemoteTranslate {
|
|||
*/
|
||||
async translate(options = {}) {
|
||||
let actor = this._browser.browsingContext.currentWindowGlobal.getActor("Translation");
|
||||
let items = null;
|
||||
let items = [];
|
||||
try {
|
||||
items = await actor.sendQuery("translate", { translator: this._translator, id: this._id });
|
||||
let jsonItems = await actor.sendQuery("translate", { translator: this._translator, id: this._id });
|
||||
if (options.libraryID !== false) {
|
||||
let itemsLeftToSave = jsonItems.length;
|
||||
let attachmentsInProgress = new Set();
|
||||
let doneHandlersInvoked = false;
|
||||
let itemSaver = new Zotero.Translate.ItemSaver({
|
||||
libraryID: options.libraryID,
|
||||
collections: options.collections,
|
||||
|
@ -154,22 +173,43 @@ class RemoteTranslate {
|
|||
// proxy: unimplemented in the client
|
||||
});
|
||||
|
||||
// Call itemDone on each completed item
|
||||
let invokeDoneHandlersIfDone = () => {
|
||||
if (itemsLeftToSave || attachmentsInProgress.size || doneHandlersInvoked) {
|
||||
return;
|
||||
}
|
||||
// Call done (saved in #setHandler() above) at the end
|
||||
// The Zotero.Translate instance running in the content process has already tried to call done by now,
|
||||
// but we prevented it from reaching the caller. Now that we've run ItemSaver#saveItems() on this side,
|
||||
// we can pass it through.
|
||||
this._callDoneHandlers(this._wasSuccess);
|
||||
doneHandlersInvoked = true;
|
||||
};
|
||||
let itemsDoneCallback = (jsonItems, dbItems) => {
|
||||
for (let i = 0; i < jsonItems.length; i++) {
|
||||
// Call itemDone on each completed item
|
||||
for (let i = 0; i < dbItems.length; i++) {
|
||||
let jsonItem = jsonItems[i];
|
||||
let dbItem = dbItems[i];
|
||||
TranslationManager.runHandler(this._id, 'itemDone', dbItem, jsonItem);
|
||||
}
|
||||
items.push(...dbItems);
|
||||
itemsLeftToSave -= dbItems.length;
|
||||
invokeDoneHandlersIfDone();
|
||||
};
|
||||
await itemSaver.saveItems(items, () => {}, itemsDoneCallback);
|
||||
let attachmentCallback = (attachment, progress) => {
|
||||
if (progress === 100 || progress === false) {
|
||||
attachmentsInProgress.delete(attachment);
|
||||
}
|
||||
else {
|
||||
attachmentsInProgress.add(attachment);
|
||||
}
|
||||
invokeDoneHandlersIfDone();
|
||||
};
|
||||
|
||||
await itemSaver.saveItems(jsonItems, attachmentCallback, itemsDoneCallback);
|
||||
}
|
||||
else {
|
||||
items.push(...jsonItems);
|
||||
}
|
||||
|
||||
// And call done (saved in #setHandler() above) at the end
|
||||
// The Zotero.Translate instance running in the content process has already tried to call done by now,
|
||||
// but we prevented it from reaching the caller. Now that we've run ItemSaver#saveItems() on this side,
|
||||
// we can pass it through.
|
||||
this._callDoneHandlers(this._wasSuccess);
|
||||
}
|
||||
catch (e) {
|
||||
this._callDoneHandlers(false);
|
||||
|
|
|
@ -7,8 +7,9 @@ const Zotero = Components.classes['@zotero.org/Zotero;1']
|
|||
const TranslationManager = new class {
|
||||
_registeredRemoteTranslates = new Map();
|
||||
|
||||
add(id) {
|
||||
add(id, remoteTranslate) {
|
||||
this._registeredRemoteTranslates.set(id, {
|
||||
remoteTranslate,
|
||||
translatorProvider: null,
|
||||
handlers: {},
|
||||
});
|
||||
|
@ -37,18 +38,24 @@ const TranslationManager = new class {
|
|||
this._registeredRemoteTranslates.get(id).handlers[name] = [handler];
|
||||
}
|
||||
}
|
||||
|
||||
removeHandler(id, name, handler) {
|
||||
this._registeredRemoteTranslates.get(id).handlers[name]
|
||||
= this._registeredRemoteTranslates.get(id).handlers[name].filter(h => h !== handler);
|
||||
}
|
||||
|
||||
clearHandlers(id, name) {
|
||||
this._registeredRemoteTranslates.get(id).handlers[name] = null;
|
||||
}
|
||||
|
||||
async runHandler(id, name, ...args) {
|
||||
let remoteTranslate = this._registeredRemoteTranslates.get(id).remoteTranslate;
|
||||
let handlers = this._registeredRemoteTranslates.get(id).handlers[name];
|
||||
let returnValue = null;
|
||||
if (handlers) {
|
||||
for (let handler of handlers) {
|
||||
try {
|
||||
returnValue = await handler(...args);
|
||||
returnValue = await handler(remoteTranslate, ...args);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
|
|
|
@ -849,7 +849,7 @@ Zotero.Attachments = new function(){
|
|||
* @return {Promise<Zotero.Item>} - A promise for the created attachment item
|
||||
*/
|
||||
this.importFromDocument = Zotero.Promise.coroutine(function* (options) {
|
||||
Zotero.debug('Importing attachment from document');
|
||||
Zotero.debug('Importing attachment from ' + (options.document ? 'document' : 'browser'));
|
||||
|
||||
var libraryID = options.libraryID;
|
||||
var document = options.document;
|
||||
|
|
Loading…
Reference in a new issue