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;
|
_wasSuccess = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
TranslationManager.add(this._id);
|
TranslationManager.add(this._id, this);
|
||||||
TranslationManager.setHandler(this._id, 'done', success => this._wasSuccess = success);
|
TranslationManager.setHandler(this._id, 'done', (_, success) => this._wasSuccess = success);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +86,23 @@ class RemoteTranslate {
|
||||||
this._doneHandlers.push(handler);
|
this._doneHandlers.push(handler);
|
||||||
}
|
}
|
||||||
else {
|
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 = {}) {
|
async translate(options = {}) {
|
||||||
let actor = this._browser.browsingContext.currentWindowGlobal.getActor("Translation");
|
let actor = this._browser.browsingContext.currentWindowGlobal.getActor("Translation");
|
||||||
let items = null;
|
let items = [];
|
||||||
try {
|
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) {
|
if (options.libraryID !== false) {
|
||||||
|
let itemsLeftToSave = jsonItems.length;
|
||||||
|
let attachmentsInProgress = new Set();
|
||||||
|
let doneHandlersInvoked = false;
|
||||||
let itemSaver = new Zotero.Translate.ItemSaver({
|
let itemSaver = new Zotero.Translate.ItemSaver({
|
||||||
libraryID: options.libraryID,
|
libraryID: options.libraryID,
|
||||||
collections: options.collections,
|
collections: options.collections,
|
||||||
|
@ -154,22 +173,43 @@ class RemoteTranslate {
|
||||||
// proxy: unimplemented in the client
|
// proxy: unimplemented in the client
|
||||||
});
|
});
|
||||||
|
|
||||||
// Call itemDone on each completed item
|
let invokeDoneHandlersIfDone = () => {
|
||||||
let itemsDoneCallback = (jsonItems, dbItems) => {
|
if (itemsLeftToSave || attachmentsInProgress.size || doneHandlersInvoked) {
|
||||||
for (let i = 0; i < jsonItems.length; i++) {
|
return;
|
||||||
let jsonItem = jsonItems[i];
|
|
||||||
let dbItem = dbItems[i];
|
|
||||||
TranslationManager.runHandler(this._id, 'itemDone', dbItem, jsonItem);
|
|
||||||
}
|
}
|
||||||
};
|
// Call done (saved in #setHandler() above) at the end
|
||||||
await itemSaver.saveItems(items, () => {}, itemsDoneCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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,
|
// 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,
|
// but we prevented it from reaching the caller. Now that we've run ItemSaver#saveItems() on this side,
|
||||||
// we can pass it through.
|
// we can pass it through.
|
||||||
this._callDoneHandlers(this._wasSuccess);
|
this._callDoneHandlers(this._wasSuccess);
|
||||||
|
doneHandlersInvoked = true;
|
||||||
|
};
|
||||||
|
let itemsDoneCallback = (jsonItems, dbItems) => {
|
||||||
|
// 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();
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
this._callDoneHandlers(false);
|
this._callDoneHandlers(false);
|
||||||
|
|
|
@ -7,8 +7,9 @@ const Zotero = Components.classes['@zotero.org/Zotero;1']
|
||||||
const TranslationManager = new class {
|
const TranslationManager = new class {
|
||||||
_registeredRemoteTranslates = new Map();
|
_registeredRemoteTranslates = new Map();
|
||||||
|
|
||||||
add(id) {
|
add(id, remoteTranslate) {
|
||||||
this._registeredRemoteTranslates.set(id, {
|
this._registeredRemoteTranslates.set(id, {
|
||||||
|
remoteTranslate,
|
||||||
translatorProvider: null,
|
translatorProvider: null,
|
||||||
handlers: {},
|
handlers: {},
|
||||||
});
|
});
|
||||||
|
@ -38,17 +39,23 @@ const TranslationManager = new class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeHandler(id, name, handler) {
|
||||||
|
this._registeredRemoteTranslates.get(id).handlers[name]
|
||||||
|
= this._registeredRemoteTranslates.get(id).handlers[name].filter(h => h !== handler);
|
||||||
|
}
|
||||||
|
|
||||||
clearHandlers(id, name) {
|
clearHandlers(id, name) {
|
||||||
this._registeredRemoteTranslates.get(id).handlers[name] = null;
|
this._registeredRemoteTranslates.get(id).handlers[name] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async runHandler(id, name, ...args) {
|
async runHandler(id, name, ...args) {
|
||||||
|
let remoteTranslate = this._registeredRemoteTranslates.get(id).remoteTranslate;
|
||||||
let handlers = this._registeredRemoteTranslates.get(id).handlers[name];
|
let handlers = this._registeredRemoteTranslates.get(id).handlers[name];
|
||||||
let returnValue = null;
|
let returnValue = null;
|
||||||
if (handlers) {
|
if (handlers) {
|
||||||
for (let handler of handlers) {
|
for (let handler of handlers) {
|
||||||
try {
|
try {
|
||||||
returnValue = await handler(...args);
|
returnValue = await handler(remoteTranslate, ...args);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.logError(e);
|
Zotero.logError(e);
|
||||||
|
|
|
@ -849,7 +849,7 @@ Zotero.Attachments = new function(){
|
||||||
* @return {Promise<Zotero.Item>} - A promise for the created attachment item
|
* @return {Promise<Zotero.Item>} - A promise for the created attachment item
|
||||||
*/
|
*/
|
||||||
this.importFromDocument = Zotero.Promise.coroutine(function* (options) {
|
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 libraryID = options.libraryID;
|
||||||
var document = options.document;
|
var document = options.document;
|
||||||
|
|
Loading…
Add table
Reference in a new issue