ensure Backend prepare in other places

This commit is contained in:
siikamiika 2020-03-02 04:51:45 +02:00
parent e6e5f23cf8
commit 967e99b7f6
7 changed files with 37 additions and 41 deletions

View File

@ -48,7 +48,7 @@ class Backend {
this.messageToken = yomichan.generateId(16); this.messageToken = yomichan.generateId(16);
this._messageHandlers = new Map([ this._messageHandlers = new Map([
['isBackendReady', this._onApiIsBackendReady.bind(this)], ['yomichanOnline', this._onApiYomichanOnline.bind(this)],
['optionsSchemaGet', this._onApiOptionsSchemaGet.bind(this)], ['optionsSchemaGet', this._onApiOptionsSchemaGet.bind(this)],
['optionsGet', this._onApiOptionsGet.bind(this)], ['optionsGet', this._onApiOptionsGet.bind(this)],
['optionsGetFull', this._onApiOptionsGetFull.bind(this)], ['optionsGetFull', this._onApiOptionsGetFull.bind(this)],
@ -114,17 +114,22 @@ class Backend {
} }
this.clipboardMonitor.onClipboardText = this._onClipboardText.bind(this); this.clipboardMonitor.onClipboardText = this._onClipboardText.bind(this);
this._sendMessageAllTabs('backendPrepared');
}
_sendMessageAllTabs(action, params={}) {
const callback = () => this.checkLastError(chrome.runtime.lastError);
chrome.tabs.query({}, (tabs) => {
for (const tab of tabs) {
chrome.tabs.sendMessage(tab.id, {action, params}, callback);
}
});
} }
onOptionsUpdated(source) { onOptionsUpdated(source) {
this.applyOptions(); this.applyOptions();
this._sendMessageAllTabs('optionsUpdated', {source});
const callback = () => this.checkLastError(chrome.runtime.lastError);
chrome.tabs.query({}, (tabs) => {
for (const tab of tabs) {
chrome.tabs.sendMessage(tab.id, {action: 'optionsUpdated', params: {source}}, callback);
}
});
} }
onMessage({action, params}, sender, callback) { onMessage({action, params}, sender, callback) {
@ -268,8 +273,11 @@ class Backend {
// Message handlers // Message handlers
async _onApiIsBackendReady() { async _onApiYomichanOnline(_params, sender) {
return true; const tabId = sender.tab.id;
return new Promise((resolve) => {
chrome.tabs.sendMessage(tabId, {action: 'backendPrepared'}, resolve);
});
} }
async _onApiOptionsSchemaGet() { async _onApiOptionsSchemaGet() {

View File

@ -19,6 +19,8 @@
/*global apiOptionsGet*/ /*global apiOptionsGet*/
async function searchFrontendSetup() { async function searchFrontendSetup() {
await yomichan.prepare();
const optionsContext = { const optionsContext = {
depth: 0, depth: 0,
url: window.location.href url: window.location.href

View File

@ -68,9 +68,8 @@ class DisplaySearch extends Display {
async prepare() { async prepare() {
try { try {
const superPromise = super.prepare(); await super.prepare();
const queryParserPromise = this.queryParser.prepare(); await this.queryParser.prepare();
await Promise.all([superPromise, queryParserPromise]);
const {queryParams: {query='', mode=''}} = parseUrl(window.location.href); const {queryParams: {query='', mode=''}} = parseUrl(window.location.href);

View File

@ -52,6 +52,7 @@ class Frontend extends TextScanner {
async prepare() { async prepare() {
try { try {
await yomichan.prepare();
await this.updateOptions(); await this.updateOptions();
const {zoomFactor} = await apiGetZoom(); const {zoomFactor} = await apiGetZoom();
this._pageZoomFactor = zoomFactor; this._pageZoomFactor = zoomFactor;

View File

@ -122,30 +122,6 @@ function apiGetDefaultAnkiFieldTemplates() {
} }
function _apiInvoke(action, params={}) { function _apiInvoke(action, params={}) {
if (!_isBackendReady) {
if (_isBackendReadyPromise === null) {
_isBackendReadyPromise = new Promise((resolve) => (_isBackendReadyResolve = resolve));
const checkBackendReady = async () => {
try {
if (await _apiInvokeRaw('isBackendReady')) {
_isBackendReady = true;
_isBackendReadyResolve();
}
} catch (e) {
// NOP
}
setTimeout(checkBackendReady, 100); // poll Backend until it responds
};
checkBackendReady();
}
return _isBackendReadyPromise.then(
() => _apiInvokeRaw(action, params)
);
}
return _apiInvokeRaw(action, params);
}
function _apiInvokeRaw(action, params={}) {
const data = {action, params}; const data = {action, params};
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
@ -172,7 +148,3 @@ function _apiInvokeRaw(action, params={}) {
function _apiCheckLastError() { function _apiCheckLastError() {
// NOP // NOP
} }
let _isBackendReady = false;
let _isBackendReadyResolve = null;
let _isBackendReadyPromise = null;

View File

@ -269,17 +269,26 @@ const yomichan = (() => {
constructor() { constructor() {
super(); super();
this._isBackendPreparedResolve = null;
this._isBackendPreparedPromise = new Promise((resolve) => (this._isBackendPreparedResolve = resolve));
this._messageHandlers = new Map([ this._messageHandlers = new Map([
['backendPrepared', this._onBackendPrepared.bind(this)],
['getUrl', this._onMessageGetUrl.bind(this)], ['getUrl', this._onMessageGetUrl.bind(this)],
['optionsUpdated', this._onMessageOptionsUpdated.bind(this)], ['optionsUpdated', this._onMessageOptionsUpdated.bind(this)],
['zoomChanged', this._onMessageZoomChanged.bind(this)] ['zoomChanged', this._onMessageZoomChanged.bind(this)]
]); ]);
chrome.runtime.onMessage.addListener(this._onMessage.bind(this)); chrome.runtime.onMessage.addListener(this._onMessage.bind(this));
chrome.runtime.sendMessage({action: 'yomichanOnline'});
} }
// Public // Public
prepare() {
return this._isBackendPreparedPromise;
}
generateId(length) { generateId(length) {
const array = new Uint8Array(length); const array = new Uint8Array(length);
window.crypto.getRandomValues(array); window.crypto.getRandomValues(array);
@ -305,6 +314,10 @@ const yomichan = (() => {
return false; return false;
} }
_onBackendPrepared() {
this._isBackendPreparedResolve();
}
_onMessageGetUrl() { _onMessageGetUrl() {
return {url: window.location.href}; return {url: window.location.href};
} }

View File

@ -153,6 +153,7 @@ class Display {
} }
async prepare(options=null) { async prepare(options=null) {
await yomichan.prepare();
const displayGeneratorPromise = this.displayGenerator.prepare(); const displayGeneratorPromise = this.displayGenerator.prepare();
const updateOptionsPromise = this.updateOptions(options); const updateOptionsPromise = this.updateOptions(options);
await Promise.all([displayGeneratorPromise, updateOptionsPromise]); await Promise.all([displayGeneratorPromise, updateOptionsPromise]);