Immediate backend event handlers (#555)
* Add function to await until prepare is completed * Create BackendEventHandler to synchronously set up event handling
This commit is contained in:
parent
9767b76553
commit
839e306cac
@ -75,9 +75,15 @@ class Backend {
|
||||
|
||||
this.popupWindow = null;
|
||||
|
||||
this._defaultBrowserActionTitle = null;
|
||||
this._isPrepared = false;
|
||||
this._prepareError = false;
|
||||
this._preparePromise = null;
|
||||
this._prepareCompletePromise = new Promise((resolve, reject) => {
|
||||
this._prepareCompleteResolve = resolve;
|
||||
this._prepareCompleteReject = reject;
|
||||
});
|
||||
|
||||
this._defaultBrowserActionTitle = null;
|
||||
this._badgePrepareDelayTimer = null;
|
||||
this._logErrorLevel = null;
|
||||
|
||||
@ -134,7 +140,26 @@ class Backend {
|
||||
]);
|
||||
}
|
||||
|
||||
async prepare() {
|
||||
prepare() {
|
||||
if (this._preparePromise === null) {
|
||||
const promise = this._prepareInternal();
|
||||
promise.then(
|
||||
(value) => {
|
||||
this._isPrepared = true;
|
||||
this._prepareCompleteResolve(value);
|
||||
},
|
||||
(error) => {
|
||||
this._prepareError = true;
|
||||
this._prepareCompleteReject(error);
|
||||
}
|
||||
);
|
||||
promise.finally(() => this._updateBadge());
|
||||
this._preparePromise = promise;
|
||||
}
|
||||
return this._prepareCompletePromise;
|
||||
}
|
||||
|
||||
async _prepareInternal() {
|
||||
try {
|
||||
this._defaultBrowserActionTitle = await this._getBrowserIconTitle();
|
||||
this._badgePrepareDelayTimer = setTimeout(() => {
|
||||
@ -156,15 +181,6 @@ class Backend {
|
||||
|
||||
this.onOptionsUpdated('background');
|
||||
|
||||
if (isObject(chrome.commands) && isObject(chrome.commands.onCommand)) {
|
||||
chrome.commands.onCommand.addListener(this._runCommand.bind(this));
|
||||
}
|
||||
if (isObject(chrome.tabs) && isObject(chrome.tabs.onZoomChange)) {
|
||||
chrome.tabs.onZoomChange.addListener(this._onZoomChange.bind(this));
|
||||
}
|
||||
chrome.runtime.onMessage.addListener(this.onMessage.bind(this));
|
||||
chrome.runtime.onConnect.addListener(this._onConnect.bind(this));
|
||||
|
||||
const options = this.getOptions(this.optionsContext);
|
||||
if (options.general.showGuide) {
|
||||
chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')});
|
||||
@ -175,10 +191,7 @@ class Backend {
|
||||
this._sendMessageAllTabs('backendPrepared');
|
||||
const callback = () => this.checkLastError(chrome.runtime.lastError);
|
||||
chrome.runtime.sendMessage({action: 'backendPrepared'}, callback);
|
||||
|
||||
this._isPrepared = true;
|
||||
} catch (e) {
|
||||
this._prepareError = true;
|
||||
yomichan.logError(e);
|
||||
throw e;
|
||||
} finally {
|
||||
@ -186,15 +199,33 @@ class Backend {
|
||||
clearTimeout(this._badgePrepareDelayTimer);
|
||||
this._badgePrepareDelayTimer = null;
|
||||
}
|
||||
|
||||
this._updateBadge();
|
||||
}
|
||||
}
|
||||
|
||||
prepareComplete() {
|
||||
return this._prepareCompletePromise;
|
||||
}
|
||||
|
||||
isPrepared() {
|
||||
return this._isPrepared;
|
||||
}
|
||||
|
||||
handleCommand(...args) {
|
||||
return this._runCommand(...args);
|
||||
}
|
||||
|
||||
handleZoomChange(...args) {
|
||||
return this._onZoomChange(...args);
|
||||
}
|
||||
|
||||
handleConnect(...args) {
|
||||
return this._onConnect(...args);
|
||||
}
|
||||
|
||||
handleMessage(...args) {
|
||||
return this.onMessage(...args);
|
||||
}
|
||||
|
||||
_sendMessageAllTabs(action, params={}) {
|
||||
const callback = () => this.checkLastError(chrome.runtime.lastError);
|
||||
chrome.tabs.query({}, (tabs) => {
|
||||
@ -1293,3 +1324,57 @@ class Backend {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BackendEventHandler {
|
||||
constructor(backend) {
|
||||
this._backend = backend;
|
||||
}
|
||||
|
||||
prepare() {
|
||||
if (isObject(chrome.commands) && isObject(chrome.commands.onCommand)) {
|
||||
const onCommand = this._createGenericEventHandler((...args) => this._backend.handleCommand(...args));
|
||||
chrome.commands.onCommand.addListener(onCommand);
|
||||
}
|
||||
|
||||
if (isObject(chrome.tabs) && isObject(chrome.tabs.onZoomChange)) {
|
||||
const onZoomChange = this._createGenericEventHandler((...args) => this._backend.handleZoomChange(...args));
|
||||
chrome.tabs.onZoomChange.addListener(onZoomChange);
|
||||
}
|
||||
|
||||
const onConnect = this._createGenericEventHandler((...args) => this._backend.handleConnect(...args));
|
||||
chrome.runtime.onConnect.addListener(onConnect);
|
||||
|
||||
const onMessage = this._onMessage.bind(this);
|
||||
chrome.runtime.onMessage.addListener(onMessage);
|
||||
}
|
||||
|
||||
// Event handlers
|
||||
|
||||
_createGenericEventHandler(handler) {
|
||||
return this._onGenericEvent.bind(this, handler);
|
||||
}
|
||||
|
||||
_onGenericEvent(handler, ...args) {
|
||||
if (this._backend.isPrepared()) {
|
||||
handler(...args);
|
||||
return;
|
||||
}
|
||||
|
||||
this._backend.prepareComplete().then(
|
||||
() => { handler(...args); },
|
||||
() => {} // NOP
|
||||
);
|
||||
}
|
||||
|
||||
_onMessage(message, sender, sendResponse) {
|
||||
if (this._backend.isPrepared()) {
|
||||
return this._backend.handleMessage(message, sender, sendResponse);
|
||||
}
|
||||
|
||||
this._backend.prepareComplete().then(
|
||||
() => { this._backend.handleMessage(message, sender, sendResponse); },
|
||||
() => { sendResponse(); } // NOP
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -17,12 +17,15 @@
|
||||
|
||||
/* global
|
||||
* Backend
|
||||
* BackendEventHandler
|
||||
*/
|
||||
|
||||
(async () => {
|
||||
(() => {
|
||||
const backend = new Backend();
|
||||
const backendEventHandler = new BackendEventHandler(backend);
|
||||
backendEventHandler.prepare();
|
||||
if (typeof window === 'object' && window !== null) {
|
||||
window.yomichanBackend = backend;
|
||||
}
|
||||
await backend.prepare();
|
||||
backend.prepare();
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user