temporary listener abstraction

This commit is contained in:
siikamiika 2020-03-22 04:55:16 +02:00
parent 9fe1e38afb
commit d88635cbb2
3 changed files with 50 additions and 21 deletions

View File

@ -44,17 +44,14 @@ class FrameOffsetForwarder {
async applyOffset(x, y) { async applyOffset(x, y) {
const uniqueId = yomichan.generateId(16); const uniqueId = yomichan.generateId(16);
let frameOffsetResolve = null; const frameOffsetPromise = yomichan.getTemporaryListenerResult(
const frameOffsetPromise = new Promise((resolve) => (frameOffsetResolve = resolve)); chrome.runtime.onMessage,
({action, params}, {resolve}) => {
const runtimeMessageCallback = ({action, params}, sender, callback) => { if (action === 'frameOffset' && isObject(params) && params.uniqueId === uniqueId) {
if (action === 'frameOffset' && isObject(params) && params.uniqueId === uniqueId) { resolve(params);
chrome.runtime.onMessage.removeListener(runtimeMessageCallback); }
callback();
frameOffsetResolve(params);
} }
}; );
chrome.runtime.onMessage.addListener(runtimeMessageCallback);
window.parent.postMessage({ window.parent.postMessage({
action: 'getFrameOffset', action: 'getFrameOffset',

View File

@ -32,19 +32,15 @@ async function main() {
let popup; let popup;
if (!proxy && (window !== window.parent)) { if (!proxy && (window !== window.parent)) {
let rootPopupInformationResolve; const rootPopupInformationPromise = yomichan.getTemporaryListenerResult(
const rootPopupInformationPromise = new Promise((resolve) => (rootPopupInformationResolve = resolve)); chrome.runtime.onMessage,
({action, params}, {resolve}) => {
const runtimeMessageCallback = ({action, params}, sender, callback) => { if (action === 'rootPopupInformation') {
if (action === 'rootPopupInformation') { resolve(params);
chrome.runtime.onMessage.removeListener(runtimeMessageCallback); }
callback();
rootPopupInformationResolve(params);
} }
}; );
chrome.runtime.onMessage.addListener(runtimeMessageCallback);
apiForward('rootPopupRequestInformationBroadcast'); apiForward('rootPopupRequestInformationBroadcast');
const {popupId, frameId} = await rootPopupInformationPromise; const {popupId, frameId} = await rootPopupInformationPromise;
const frameOffsetForwarder = new FrameOffsetForwarder(); const frameOffsetForwarder = new FrameOffsetForwarder();

View File

@ -312,6 +312,42 @@ const yomichan = (() => {
this.trigger('orphaned', {error}); this.trigger('orphaned', {error});
} }
getTemporaryListenerResult(eventHandler, userCallback, timeout=30000) {
let resolved = false;
let resolve;
let reject;
const listenerPromise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
if (eventHandler === chrome.runtime.onMessage) {
const runtimeMessageCallback = ({action, params}, sender, sendResponse) => {
const cleanupResolve = (value) => {
resolved = true;
eventHandler.removeListener(runtimeMessageCallback);
sendResponse();
resolve(value);
};
setTimeout(() => {
if (!resolved) {
reject(new Error(`Listener timed out in ${timeout} ms`));
eventHandler.removeListener(runtimeMessageCallback);
}
}, timeout);
userCallback({action, params}, {resolve: cleanupResolve, sender});
};
eventHandler.addListener(runtimeMessageCallback);
} else {
throw new Error('Event handler type not supported');
}
return listenerPromise;
}
// Private // Private
_onMessage({action, params}, sender, callback) { _onMessage({action, params}, sender, callback) {