temporary listener abstraction
This commit is contained in:
parent
9fe1e38afb
commit
d88635cbb2
@ -44,17 +44,14 @@ class FrameOffsetForwarder {
|
||||
async applyOffset(x, y) {
|
||||
const uniqueId = yomichan.generateId(16);
|
||||
|
||||
let frameOffsetResolve = null;
|
||||
const frameOffsetPromise = new Promise((resolve) => (frameOffsetResolve = resolve));
|
||||
|
||||
const runtimeMessageCallback = ({action, params}, sender, callback) => {
|
||||
const frameOffsetPromise = yomichan.getTemporaryListenerResult(
|
||||
chrome.runtime.onMessage,
|
||||
({action, params}, {resolve}) => {
|
||||
if (action === 'frameOffset' && isObject(params) && params.uniqueId === uniqueId) {
|
||||
chrome.runtime.onMessage.removeListener(runtimeMessageCallback);
|
||||
callback();
|
||||
frameOffsetResolve(params);
|
||||
resolve(params);
|
||||
}
|
||||
};
|
||||
chrome.runtime.onMessage.addListener(runtimeMessageCallback);
|
||||
}
|
||||
);
|
||||
|
||||
window.parent.postMessage({
|
||||
action: 'getFrameOffset',
|
||||
|
@ -32,19 +32,15 @@ async function main() {
|
||||
|
||||
let popup;
|
||||
if (!proxy && (window !== window.parent)) {
|
||||
let rootPopupInformationResolve;
|
||||
const rootPopupInformationPromise = new Promise((resolve) => (rootPopupInformationResolve = resolve));
|
||||
|
||||
const runtimeMessageCallback = ({action, params}, sender, callback) => {
|
||||
const rootPopupInformationPromise = yomichan.getTemporaryListenerResult(
|
||||
chrome.runtime.onMessage,
|
||||
({action, params}, {resolve}) => {
|
||||
if (action === 'rootPopupInformation') {
|
||||
chrome.runtime.onMessage.removeListener(runtimeMessageCallback);
|
||||
callback();
|
||||
rootPopupInformationResolve(params);
|
||||
resolve(params);
|
||||
}
|
||||
};
|
||||
chrome.runtime.onMessage.addListener(runtimeMessageCallback);
|
||||
}
|
||||
);
|
||||
apiForward('rootPopupRequestInformationBroadcast');
|
||||
|
||||
const {popupId, frameId} = await rootPopupInformationPromise;
|
||||
|
||||
const frameOffsetForwarder = new FrameOffsetForwarder();
|
||||
|
@ -312,6 +312,42 @@ const yomichan = (() => {
|
||||
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
|
||||
|
||||
_onMessage({action, params}, sender, callback) {
|
||||
|
Loading…
Reference in New Issue
Block a user