summaryrefslogtreecommitdiff
path: root/ext/mixed
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mixed')
-rw-r--r--ext/mixed/js/core.js51
1 files changed, 44 insertions, 7 deletions
diff --git a/ext/mixed/js/core.js b/ext/mixed/js/core.js
index fd762e97..db7fc69b 100644
--- a/ext/mixed/js/core.js
+++ b/ext/mixed/js/core.js
@@ -278,11 +278,16 @@ const yomichan = (() => {
constructor() {
super();
- this._isBackendPreparedResolve = null;
- this._isBackendPreparedPromise = new Promise((resolve) => (this._isBackendPreparedResolve = resolve));
+ this._isBackendPreparedPromise = this.getTemporaryListenerResult(
+ chrome.runtime.onMessage,
+ ({action}, {resolve}) => {
+ if (action === 'backendPrepared') {
+ resolve();
+ }
+ }
+ );
this._messageHandlers = new Map([
- ['backendPrepared', this._onBackendPrepared.bind(this)],
['getUrl', this._onMessageGetUrl.bind(this)],
['optionsUpdated', this._onMessageOptionsUpdated.bind(this)],
['zoomChanged', this._onMessageZoomChanged.bind(this)]
@@ -312,6 +317,42 @@ const yomichan = (() => {
this.trigger('orphaned', {error});
}
+ getTemporaryListenerResult(eventHandler, userCallback, timeout=null) {
+ if (!(
+ typeof eventHandler.addListener === 'function' &&
+ typeof eventHandler.removeListener === 'function'
+ )) {
+ throw new Error('Event handler type not supported');
+ }
+
+ return new Promise((resolve, reject) => {
+ const runtimeMessageCallback = ({action, params}, sender, sendResponse) => {
+ let timeoutId = null;
+ if (timeout !== null) {
+ timeoutId = window.setTimeout(() => {
+ timeoutId = null;
+ eventHandler.removeListener(runtimeMessageCallback);
+ reject(new Error(`Listener timed out in ${timeout} ms`));
+ }, timeout);
+ }
+
+ const cleanupResolve = (value) => {
+ if (timeoutId !== null) {
+ window.clearTimeout(timeoutId);
+ timeoutId = null;
+ }
+ eventHandler.removeListener(runtimeMessageCallback);
+ sendResponse();
+ resolve(value);
+ };
+
+ userCallback({action, params}, {resolve: cleanupResolve, sender});
+ };
+
+ eventHandler.addListener(runtimeMessageCallback);
+ });
+ }
+
// Private
_onMessage({action, params}, sender, callback) {
@@ -323,10 +364,6 @@ const yomichan = (() => {
return false;
}
- _onBackendPrepared() {
- this._isBackendPreparedResolve();
- }
-
_onMessageGetUrl() {
return {url: window.location.href};
}