diff options
Diffstat (limited to 'ext/fg/js/popup-proxy-host.js')
-rw-r--r-- | ext/fg/js/popup-proxy-host.js | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 4dc79943..487dda90 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -19,6 +19,7 @@ /* global * FrontendApiReceiver * Popup + * apiForward * apiFrameInformationGet */ @@ -48,6 +49,12 @@ class PopupProxyHost { ['clearAutoPlayTimer', this._onApiClearAutoPlayTimer.bind(this)], ['setContentScale', this._onApiSetContentScale.bind(this)] ])); + + this._windowMessageHandlers = new Map([ + ['getIframeOffset', ({offset, uniqueId}, e) => { return this._onGetIframeOffset(offset, uniqueId, e); }] + ]); + + window.addEventListener('message', this.onMessage.bind(this), false); } getOrCreatePopup(id=null, parentId=null, depth=null) { @@ -95,7 +102,7 @@ class PopupProxyHost { return popup; } - // Message handlers + // API message handlers async _onApiGetOrCreatePopup({id, parentId}) { const popup = this.getOrCreatePopup(id, parentId); @@ -152,6 +159,30 @@ class PopupProxyHost { return popup.setContentScale(scale); } + // Window message handlers + + onMessage(e) { + const {action, params} = e.data; + const handler = this._windowMessageHandlers.get(action); + if (typeof handler !== 'function') { return; } + handler(params, e); + } + + _onGetIframeOffset(offset, uniqueId, e) { + let sourceIframe = null; + for (const iframe of document.querySelectorAll('iframe:not(.yomichan-float)')) { + if (iframe.contentWindow !== e.source) { continue; } + sourceIframe = iframe; + break; + } + if (sourceIframe === null) { return; } + + const [forwardedX, forwardedY] = offset; + const {x, y} = sourceIframe.getBoundingClientRect(); + offset = [forwardedX + x, forwardedY + y]; + apiForward('iframeOffset', {offset, uniqueId}); + } + // Private functions _getPopup(id) { |