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.popupWindow = null;
|
||||||
|
|
||||||
this._defaultBrowserActionTitle = null;
|
|
||||||
this._isPrepared = false;
|
this._isPrepared = false;
|
||||||
this._prepareError = 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._badgePrepareDelayTimer = null;
|
||||||
this._logErrorLevel = 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 {
|
try {
|
||||||
this._defaultBrowserActionTitle = await this._getBrowserIconTitle();
|
this._defaultBrowserActionTitle = await this._getBrowserIconTitle();
|
||||||
this._badgePrepareDelayTimer = setTimeout(() => {
|
this._badgePrepareDelayTimer = setTimeout(() => {
|
||||||
@ -156,15 +181,6 @@ class Backend {
|
|||||||
|
|
||||||
this.onOptionsUpdated('background');
|
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);
|
const options = this.getOptions(this.optionsContext);
|
||||||
if (options.general.showGuide) {
|
if (options.general.showGuide) {
|
||||||
chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')});
|
chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')});
|
||||||
@ -175,10 +191,7 @@ class Backend {
|
|||||||
this._sendMessageAllTabs('backendPrepared');
|
this._sendMessageAllTabs('backendPrepared');
|
||||||
const callback = () => this.checkLastError(chrome.runtime.lastError);
|
const callback = () => this.checkLastError(chrome.runtime.lastError);
|
||||||
chrome.runtime.sendMessage({action: 'backendPrepared'}, callback);
|
chrome.runtime.sendMessage({action: 'backendPrepared'}, callback);
|
||||||
|
|
||||||
this._isPrepared = true;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this._prepareError = true;
|
|
||||||
yomichan.logError(e);
|
yomichan.logError(e);
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
@ -186,15 +199,33 @@ class Backend {
|
|||||||
clearTimeout(this._badgePrepareDelayTimer);
|
clearTimeout(this._badgePrepareDelayTimer);
|
||||||
this._badgePrepareDelayTimer = null;
|
this._badgePrepareDelayTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateBadge();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepareComplete() {
|
||||||
|
return this._prepareCompletePromise;
|
||||||
|
}
|
||||||
|
|
||||||
isPrepared() {
|
isPrepared() {
|
||||||
return this._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={}) {
|
_sendMessageAllTabs(action, params={}) {
|
||||||
const callback = () => this.checkLastError(chrome.runtime.lastError);
|
const callback = () => this.checkLastError(chrome.runtime.lastError);
|
||||||
chrome.tabs.query({}, (tabs) => {
|
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
|
/* global
|
||||||
* Backend
|
* Backend
|
||||||
|
* BackendEventHandler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(async () => {
|
(() => {
|
||||||
const backend = new Backend();
|
const backend = new Backend();
|
||||||
|
const backendEventHandler = new BackendEventHandler(backend);
|
||||||
|
backendEventHandler.prepare();
|
||||||
if (typeof window === 'object' && window !== null) {
|
if (typeof window === 'object' && window !== null) {
|
||||||
window.yomichanBackend = backend;
|
window.yomichanBackend = backend;
|
||||||
}
|
}
|
||||||
await backend.prepare();
|
backend.prepare();
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user