Refactor some frontend cross-frame communication (#733)

* Refactor iframe proxy setup

* Simplify document title acquisition
This commit is contained in:
toasted-nutbread 2020-08-15 17:36:42 -04:00 committed by GitHub
parent d5865db457
commit 4d6851ec32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 59 deletions

View File

@ -69,25 +69,8 @@ class DisplayFloat extends Display {
async getDocumentTitle() { async getDocumentTitle() {
try { try {
const uniqueId = yomichan.generateId(16); const targetFrameId = 0;
const {title} = await api.crossFrame.invoke(targetFrameId, 'getDocumentInformation');
const promise = yomichan.getTemporaryListenerResult(
chrome.runtime.onMessage,
({action, params}, {resolve}) => {
if (
action === 'documentInformationBroadcast' &&
isObject(params) &&
params.uniqueId === uniqueId &&
params.frameId === 0
) {
resolve(params);
}
},
2000
);
api.broadcastTab('requestDocumentInformationBroadcast', {uniqueId});
const {title} = await promise;
return title; return title;
} catch (e) { } catch (e) {
return ''; return '';

View File

@ -66,8 +66,7 @@ class Frontend {
this._runtimeMessageHandlers = new Map([ this._runtimeMessageHandlers = new Map([
['popupSetVisibleOverride', {async: false, handler: this._onMessagePopupSetVisibleOverride.bind(this)}], ['popupSetVisibleOverride', {async: false, handler: this._onMessagePopupSetVisibleOverride.bind(this)}],
['rootPopupRequestInformationBroadcast', {async: false, handler: this._onMessageRootPopupRequestInformationBroadcast.bind(this)}], ['requestFrontendReadyBroadcast', {async: false, handler: this._onMessageRequestFrontendReadyBroadcast.bind(this)}]
['requestDocumentInformationBroadcast', {async: false, handler: this._onMessageRequestDocumentInformationBroadcast.bind(this)}]
]); ]);
} }
@ -116,11 +115,13 @@ class Frontend {
api.crossFrame.registerHandlers([ api.crossFrame.registerHandlers([
['getUrl', {async: false, handler: this._onApiGetUrl.bind(this)}], ['getUrl', {async: false, handler: this._onApiGetUrl.bind(this)}],
['closePopup', {async: false, handler: this._onApiClosePopup.bind(this)}], ['closePopup', {async: false, handler: this._onApiClosePopup.bind(this)}],
['copySelection', {async: false, handler: this._onApiCopySelection.bind(this)}] ['copySelection', {async: false, handler: this._onApiCopySelection.bind(this)}],
['getPopupInfo', {async: false, handler: this._onApiGetPopupInfo.bind(this)}],
['getDocumentInformation', {async: false, handler: this._onApiGetDocumentInformation.bind(this)}]
]); ]);
this._updateContentScale(); this._updateContentScale();
this._broadcastRootPopupInformation(); this._signalFrontendReady();
} }
setDisabledOverride(disabled) { setDisabledOverride(disabled) {
@ -169,12 +170,8 @@ class Frontend {
this._popup.setVisibleOverride(visible); this._popup.setVisibleOverride(visible);
} }
_onMessageRootPopupRequestInformationBroadcast() { _onMessageRequestFrontendReadyBroadcast({frameId}) {
this._broadcastRootPopupInformation(); this._signalFrontendReady(frameId);
}
_onMessageRequestDocumentInformationBroadcast({uniqueId}) {
this._broadcastDocumentInformation(uniqueId);
} }
// API message handlers // API message handlers
@ -191,6 +188,18 @@ class Frontend {
document.execCommand('copy'); document.execCommand('copy');
} }
_onApiGetPopupInfo() {
return {
popupId: (this._popup !== null ? this._popup.id : null)
};
}
_onApiGetDocumentInformation() {
return {
title: document.title
};
}
// Private // Private
_onResize() { _onResize() {
@ -325,18 +334,10 @@ class Frontend {
} }
async _getIframeProxyPopup() { async _getIframeProxyPopup() {
const rootPopupInformationPromise = yomichan.getTemporaryListenerResult( const targetFrameId = 0; // Root frameId
chrome.runtime.onMessage, await this._waitForFrontendReady(targetFrameId);
({action, params}, {resolve}) => { const {popupId} = await api.crossFrame.invoke(targetFrameId, 'getPopupInfo');
if (action === 'rootPopupInformation') { const popup = new PopupProxy(popupId, 0, null, targetFrameId, this._frameId, this._frameOffsetForwarder);
resolve(params);
}
}
);
api.broadcastTab('rootPopupRequestInformationBroadcast');
const {popupId, frameId: parentFrameId} = await rootPopupInformationPromise;
const popup = new PopupProxy(popupId, 0, null, parentFrameId, this._frameId, this._frameOffsetForwarder);
popup.on('offsetNotFound', () => { popup.on('offsetNotFound', () => {
this._allowRootFramePopupProxy = false; this._allowRootFramePopupProxy = false;
this._updatePopup(); this._updatePopup();
@ -529,24 +530,29 @@ class Frontend {
} }
} }
_broadcastRootPopupInformation() { _signalFrontendReady(targetFrameId=null) {
if ( const params = {frameId: this._frameId};
this._popup !== null && if (targetFrameId === null) {
this._depth === 0 && api.broadcastTab('frontendReady', params);
this._frameId === 0 } else {
) { api.sendMessageToFrame(targetFrameId, 'frontendReady', params);
api.broadcastTab('rootPopupInformation', {
popupId: this._popup.id,
frameId: this._frameId
});
} }
} }
_broadcastDocumentInformation(uniqueId) { async _waitForFrontendReady(frameId) {
api.broadcastTab('documentInformationBroadcast', { const promise = yomichan.getTemporaryListenerResult(
uniqueId, chrome.runtime.onMessage,
frameId: this._frameId, ({action, params}, {resolve}) => {
title: document.title if (
}); action === 'frontendReady' &&
params.frameId === frameId
) {
resolve();
}
},
10000
);
api.broadcastTab('requestFrontendReadyBroadcast', {frameId: this._frameId});
await promise;
} }
} }