From 4814db8df12598c167b1e97096511f43e32c5e36 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 19 Mar 2020 02:55:31 +0200 Subject: adjust iframe popup position to root page --- ext/fg/js/popup-proxy.js | 69 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 997b1317..c1ee76ce 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -29,6 +29,12 @@ class PopupProxy { this._depth = depth; this._url = url; this._apiSender = new FrontendApiSender(); + + this._windowMessageHandlers = new Map([ + ['getIframeOffset', ({offset, uniqueId}, e) => { return this._onGetIframeOffset(offset, uniqueId, e); }] + ]); + + window.addEventListener('message', this.onMessage.bind(this), false); } // Public properties @@ -83,12 +89,19 @@ class PopupProxy { if (this._id === null) { return false; } + if (this._depth === 0) { + [x, y] = await PopupProxy._convertIframePointToRootPagePoint(x, y); + } return await this._invokeHostApi('containsPoint', {id: this._id, x, y}); } async showContent(elementRect, writingMode, type=null, details=null) { const id = await this._getPopupId(); - elementRect = PopupProxy._convertDOMRectToJson(elementRect); + let {x, y, width, height} = PopupProxy._convertDOMRectToJson(elementRect); + if (this._depth === 0) { + [x, y] = await PopupProxy._convertIframePointToRootPagePoint(x, y); + elementRect = {x, y, width, height}; + } return await this._invokeHostApi('showContent', {id, elementRect, writingMode, type, details}); } @@ -109,6 +122,31 @@ class PopupProxy { this._invokeHostApi('setContentScale', {id, 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]; + window.parent.postMessage({action: 'getIframeOffset', params: {offset, uniqueId}}, '*'); + } + + // Private _getPopupId() { @@ -131,6 +169,35 @@ class PopupProxy { return this._apiSender.invoke(action, params, `popup-proxy-host#${this._parentFrameId}`); } + static async _convertIframePointToRootPagePoint(x, y) { + const uniqueId = yomichan.generateId(16); + + let frameOffsetResolve = null; + const frameOffsetPromise = new Promise((resolve) => (frameOffsetResolve = resolve)); + + const runtimeMessageCallback = ({action, params}, sender, callback) => { + if (action === 'iframeOffset' && isObject(params) && params.uniqueId === uniqueId) { + chrome.runtime.onMessage.removeListener(runtimeMessageCallback); + callback(); + frameOffsetResolve(params); + return false; + } + }; + chrome.runtime.onMessage.addListener(runtimeMessageCallback); + + window.parent.postMessage({ + action: 'getIframeOffset', + params: { + uniqueId, + offset: [x, y] + } + }, '*'); + + const {offset} = await frameOffsetPromise; + + return offset; + } + static _convertDOMRectToJson(domRect) { return { x: domRect.x, -- cgit v1.2.3 From b996d0b1e0838673001db0580430ed4ad6d102f2 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 19 Mar 2020 15:29:49 +0200 Subject: fix and simplify --- ext/fg/js/frontend.js | 1 + ext/fg/js/popup-proxy.js | 17 ++++++----------- ext/fg/js/popup.js | 2 -- 3 files changed, 7 insertions(+), 13 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index af5341c4..d6fe7af4 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -77,6 +77,7 @@ class Frontend extends TextScanner { chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); this._updateContentScale(); + this.popup.broadcastRootPopupInformation(); } catch (e) { this.onError(e); } diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index c1ee76ce..242da04c 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -61,6 +61,10 @@ class PopupProxy { return true; } + broadcastRootPopupInformation() { + // NOP + } + async setOptions(options) { const id = await this._getPopupId(); return await this._invokeHostApi('setOptions', {id, options}); @@ -97,11 +101,11 @@ class PopupProxy { async showContent(elementRect, writingMode, type=null, details=null) { const id = await this._getPopupId(); - let {x, y, width, height} = PopupProxy._convertDOMRectToJson(elementRect); + let {x, y, width, height} = elementRect; if (this._depth === 0) { [x, y] = await PopupProxy._convertIframePointToRootPagePoint(x, y); - elementRect = {x, y, width, height}; } + elementRect = {x, y, width, height}; return await this._invokeHostApi('showContent', {id, elementRect, writingMode, type, details}); } @@ -197,13 +201,4 @@ class PopupProxy { return offset; } - - static _convertDOMRectToJson(domRect) { - return { - x: domRect.x, - y: domRect.y, - width: domRect.width, - height: domRect.height - }; - } } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 5b8724ae..4c979911 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -199,8 +199,6 @@ class Popup { } async _createInjectPromise() { - this.broadcastRootPopupInformation(); - if (this._messageToken === null) { this._messageToken = await apiGetMessageToken(); } -- cgit v1.2.3 From 09151a1a860f35b8dcbdbe9a25c09be5abeb4e37 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 19 Mar 2020 15:55:12 +0200 Subject: simplify popup proxy prepare --- ext/fg/js/frontend-initialize.js | 2 ++ ext/fg/js/popup-proxy.js | 46 +++++++++------------------------------- 2 files changed, 12 insertions(+), 36 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 7f70d9c4..352c6bd9 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -48,8 +48,10 @@ async function main() { const {popupId, frameId} = await rootPopupInformationPromise; popup = new PopupProxy(popupId, 0, null, frameId, url); + await popup.prepare(); } else if (proxy) { popup = new PopupProxy(null, depth + 1, id, parentFrameId, url); + await popup.prepare(); } else { const popupHost = new PopupProxyHost(); await popupHost.prepare(); diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 242da04c..8693ef17 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -25,7 +25,6 @@ class PopupProxy { this._parentId = parentId; this._parentFrameId = parentFrameId; this._id = id; - this._idPromise = null; this._depth = depth; this._url = url; this._apiSender = new FrontendApiSender(); @@ -57,6 +56,11 @@ class PopupProxy { // Public functions + async prepare() { + const {id} = await this._invokeHostApi('getOrCreatePopup', {id: this._id, parentId: this._parentId}); + this._id = id; + } + isProxy() { return true; } @@ -66,33 +70,22 @@ class PopupProxy { } async setOptions(options) { - const id = await this._getPopupId(); - return await this._invokeHostApi('setOptions', {id, options}); + return await this._invokeHostApi('setOptions', {id: this._id, options}); } hide(changeFocus) { - if (this._id === null) { - return; - } this._invokeHostApi('hide', {id: this._id, changeFocus}); } async isVisible() { - const id = await this._getPopupId(); - return await this._invokeHostApi('isVisible', {id}); + return await this._invokeHostApi('isVisible', {id: this._id}); } setVisibleOverride(visible) { - if (this._id === null) { - return; - } this._invokeHostApi('setVisibleOverride', {id: this._id, visible}); } async containsPoint(x, y) { - if (this._id === null) { - return false; - } if (this._depth === 0) { [x, y] = await PopupProxy._convertIframePointToRootPagePoint(x, y); } @@ -100,30 +93,24 @@ class PopupProxy { } async showContent(elementRect, writingMode, type=null, details=null) { - const id = await this._getPopupId(); let {x, y, width, height} = elementRect; if (this._depth === 0) { [x, y] = await PopupProxy._convertIframePointToRootPagePoint(x, y); } elementRect = {x, y, width, height}; - return await this._invokeHostApi('showContent', {id, elementRect, writingMode, type, details}); + return await this._invokeHostApi('showContent', {id: this._id, elementRect, writingMode, type, details}); } async setCustomCss(css) { - const id = await this._getPopupId(); - return await this._invokeHostApi('setCustomCss', {id, css}); + return await this._invokeHostApi('setCustomCss', {id: this._id, css}); } clearAutoPlayTimer() { - if (this._id === null) { - return; - } this._invokeHostApi('clearAutoPlayTimer', {id: this._id}); } async setContentScale(scale) { - const id = await this._getPopupId(); - this._invokeHostApi('setContentScale', {id, scale}); + this._invokeHostApi('setContentScale', {id: this._id, scale}); } // Window message handlers @@ -153,19 +140,6 @@ class PopupProxy { // Private - _getPopupId() { - if (this._idPromise === null) { - this._idPromise = this._getPopupIdAsync(); - } - return this._idPromise; - } - - async _getPopupIdAsync() { - const {id} = await this._invokeHostApi('getOrCreatePopup', {id: this._id, parentId: this._parentId}); - this._id = id; - return id; - } - _invokeHostApi(action, params={}) { if (typeof this._parentFrameId !== 'number') { return Promise.reject(new Error('Invalid frame')); -- cgit v1.2.3 From d20ece9f074bb9d241a902f29344e5906e3c8210 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Thu, 19 Mar 2020 17:46:05 +0200 Subject: move frame offset forwarding code to a class --- ext/bg/js/search-frontend.js | 1 + ext/fg/js/frame-offset-forwarder.js | 94 +++++++++++++++++++++++++++++++++++++ ext/fg/js/frontend-initialize.js | 6 ++- ext/fg/js/popup-proxy-host.js | 31 ------------ ext/fg/js/popup-proxy.js | 67 ++------------------------ ext/manifest.json | 1 + 6 files changed, 105 insertions(+), 95 deletions(-) create mode 100644 ext/fg/js/frame-offset-forwarder.js (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/bg/js/search-frontend.js b/ext/bg/js/search-frontend.js index 2d2aa8d4..f130a6fa 100644 --- a/ext/bg/js/search-frontend.js +++ b/ext/bg/js/search-frontend.js @@ -35,6 +35,7 @@ async function searchFrontendSetup() { const scriptSrcs = [ '/mixed/js/text-scanner.js', '/fg/js/frontend-api-receiver.js', + '/fg/js/frame-offset-forwarder.js', '/fg/js/popup.js', '/fg/js/popup-proxy-host.js', '/fg/js/frontend.js', diff --git a/ext/fg/js/frame-offset-forwarder.js b/ext/fg/js/frame-offset-forwarder.js new file mode 100644 index 00000000..b3715c2a --- /dev/null +++ b/ext/fg/js/frame-offset-forwarder.js @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* global + * apiForward + */ + +class FrameOffsetForwarder { + constructor() { + this._forwardFrameOffset = window !== window.parent ? + this._forwardFrameOffsetParent.bind(this) : + this._forwardFrameOffsetOrigin.bind(this); + + this._windowMessageHandlers = new Map([ + ['getFrameOffset', ({offset, uniqueId}, e) => { return this._onGetFrameOffset(offset, uniqueId, e); }] + ]); + + window.addEventListener('message', this.onMessage.bind(this), false); + } + + async applyOffset(x, y) { + const uniqueId = yomichan.generateId(16); + + let frameOffsetResolve = null; + const frameOffsetPromise = new Promise((resolve) => (frameOffsetResolve = resolve)); + + const runtimeMessageCallback = ({action, params}, sender, callback) => { + if (action === 'frameOffset' && isObject(params) && params.uniqueId === uniqueId) { + chrome.runtime.onMessage.removeListener(runtimeMessageCallback); + callback(); + frameOffsetResolve(params); + return false; + } + }; + chrome.runtime.onMessage.addListener(runtimeMessageCallback); + + window.parent.postMessage({ + action: 'getFrameOffset', + params: { + uniqueId, + offset: [x, y] + } + }, '*'); + + const {offset} = await frameOffsetPromise; + return offset; + } + + onMessage(e) { + const {action, params} = e.data; + const handler = this._windowMessageHandlers.get(action); + if (typeof handler !== 'function') { return; } + handler(params, e); + } + + _onGetFrameOffset(offset, uniqueId, e) { + let sourceFrame = null; + for (const frame of document.querySelectorAll('frame, iframe:not(.yomichan-float)')) { + if (frame.contentWindow !== e.source) { continue; } + sourceFrame = frame; + break; + } + if (sourceFrame === null) { return; } + + const [forwardedX, forwardedY] = offset; + const {x, y} = sourceFrame.getBoundingClientRect(); + offset = [forwardedX + x, forwardedY + y]; + + this._forwardFrameOffset(offset, uniqueId); + } + + _forwardFrameOffsetParent(offset, uniqueId) { + window.parent.postMessage({action: 'getFrameOffset', params: {offset, uniqueId}}, '*'); + } + + _forwardFrameOffsetOrigin(offset, uniqueId) { + apiForward('frameOffset', {offset, uniqueId}); + } +} diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 352c6bd9..777291fe 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -17,6 +17,7 @@ */ /* global + * FrameOffsetForwarder * Frontend * PopupProxy * PopupProxyHost @@ -47,12 +48,15 @@ async function main() { const {popupId, frameId} = await rootPopupInformationPromise; - popup = new PopupProxy(popupId, 0, null, frameId, url); + window._frameOffsetForwarder = new FrameOffsetForwarder(); + const applyFrameOffset = window._frameOffsetForwarder.applyOffset.bind(window._frameOffsetForwarder); + popup = new PopupProxy(popupId, 0, null, frameId, url, applyFrameOffset); await popup.prepare(); } else if (proxy) { popup = new PopupProxy(null, depth + 1, id, parentFrameId, url); await popup.prepare(); } else { + window._frameOffsetForwarder = new FrameOffsetForwarder(); const popupHost = new PopupProxyHost(); await popupHost.prepare(); diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 487dda90..4b136e41 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -19,7 +19,6 @@ /* global * FrontendApiReceiver * Popup - * apiForward * apiFrameInformationGet */ @@ -49,12 +48,6 @@ 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) { @@ -159,30 +152,6 @@ 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) { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 8693ef17..73148eee 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -21,19 +21,14 @@ */ class PopupProxy { - constructor(id, depth, parentId, parentFrameId, url) { + constructor(id, depth, parentId, parentFrameId, url, applyFrameOffset=async (x, y) => [x, y]) { this._parentId = parentId; this._parentFrameId = parentFrameId; this._id = id; this._depth = depth; this._url = url; this._apiSender = new FrontendApiSender(); - - this._windowMessageHandlers = new Map([ - ['getIframeOffset', ({offset, uniqueId}, e) => { return this._onGetIframeOffset(offset, uniqueId, e); }] - ]); - - window.addEventListener('message', this.onMessage.bind(this), false); + this._applyFrameOffset = applyFrameOffset; } // Public properties @@ -87,7 +82,7 @@ class PopupProxy { async containsPoint(x, y) { if (this._depth === 0) { - [x, y] = await PopupProxy._convertIframePointToRootPagePoint(x, y); + [x, y] = await this._applyFrameOffset(x, y); } return await this._invokeHostApi('containsPoint', {id: this._id, x, y}); } @@ -95,7 +90,7 @@ class PopupProxy { async showContent(elementRect, writingMode, type=null, details=null) { let {x, y, width, height} = elementRect; if (this._depth === 0) { - [x, y] = await PopupProxy._convertIframePointToRootPagePoint(x, y); + [x, y] = await this._applyFrameOffset(x, y); } elementRect = {x, y, width, height}; return await this._invokeHostApi('showContent', {id: this._id, elementRect, writingMode, type, details}); @@ -113,31 +108,6 @@ class PopupProxy { this._invokeHostApi('setContentScale', {id: this._id, 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]; - window.parent.postMessage({action: 'getIframeOffset', params: {offset, uniqueId}}, '*'); - } - - // Private _invokeHostApi(action, params={}) { @@ -146,33 +116,4 @@ class PopupProxy { } return this._apiSender.invoke(action, params, `popup-proxy-host#${this._parentFrameId}`); } - - static async _convertIframePointToRootPagePoint(x, y) { - const uniqueId = yomichan.generateId(16); - - let frameOffsetResolve = null; - const frameOffsetPromise = new Promise((resolve) => (frameOffsetResolve = resolve)); - - const runtimeMessageCallback = ({action, params}, sender, callback) => { - if (action === 'iframeOffset' && isObject(params) && params.uniqueId === uniqueId) { - chrome.runtime.onMessage.removeListener(runtimeMessageCallback); - callback(); - frameOffsetResolve(params); - return false; - } - }; - chrome.runtime.onMessage.addListener(runtimeMessageCallback); - - window.parent.postMessage({ - action: 'getIframeOffset', - params: { - uniqueId, - offset: [x, y] - } - }, '*'); - - const {offset} = await frameOffsetPromise; - - return offset; - } } diff --git a/ext/manifest.json b/ext/manifest.json index 97d59e49..98965389 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -27,6 +27,7 @@ "fg/js/frontend-api-receiver.js", "fg/js/popup.js", "fg/js/source.js", + "fg/js/frame-offset-forwarder.js", "fg/js/popup-proxy.js", "fg/js/popup-proxy-host.js", "fg/js/frontend.js", -- cgit v1.2.3 From 9fe1e38afb056164dbcc4369160bb9fd4790a2c0 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 22 Mar 2020 03:29:09 +0200 Subject: refactor --- ext/fg/js/frame-offset-forwarder.js | 15 +++++++++++---- ext/fg/js/frontend-initialize.js | 13 ++++++++----- ext/fg/js/frontend.js | 2 +- ext/fg/js/popup-proxy.js | 6 +++--- ext/fg/js/popup.js | 1 - 5 files changed, 23 insertions(+), 14 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/frame-offset-forwarder.js b/ext/fg/js/frame-offset-forwarder.js index b3715c2a..09eb89a6 100644 --- a/ext/fg/js/frame-offset-forwarder.js +++ b/ext/fg/js/frame-offset-forwarder.js @@ -22,15 +22,23 @@ class FrameOffsetForwarder { constructor() { - this._forwardFrameOffset = window !== window.parent ? + this._started = false; + + this._forwardFrameOffset = ( + window !== window.parent ? this._forwardFrameOffsetParent.bind(this) : - this._forwardFrameOffsetOrigin.bind(this); + this._forwardFrameOffsetOrigin.bind(this) + ); this._windowMessageHandlers = new Map([ - ['getFrameOffset', ({offset, uniqueId}, e) => { return this._onGetFrameOffset(offset, uniqueId, e); }] + ['getFrameOffset', ({offset, uniqueId}, e) => this._onGetFrameOffset(offset, uniqueId, e)] ]); + } + start() { + if (this._started) { return; } window.addEventListener('message', this.onMessage.bind(this), false); + this._started = true; } async applyOffset(x, y) { @@ -44,7 +52,6 @@ class FrameOffsetForwarder { chrome.runtime.onMessage.removeListener(runtimeMessageCallback); callback(); frameOffsetResolve(params); - return false; } }; chrome.runtime.onMessage.addListener(runtimeMessageCallback); diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 777291fe..51fa8d7a 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -40,23 +40,26 @@ async function main() { chrome.runtime.onMessage.removeListener(runtimeMessageCallback); callback(); rootPopupInformationResolve(params); - return false; } }; chrome.runtime.onMessage.addListener(runtimeMessageCallback); - apiForward('rootPopupInformationGet'); + apiForward('rootPopupRequestInformationBroadcast'); const {popupId, frameId} = await rootPopupInformationPromise; - window._frameOffsetForwarder = new FrameOffsetForwarder(); - const applyFrameOffset = window._frameOffsetForwarder.applyOffset.bind(window._frameOffsetForwarder); + const frameOffsetForwarder = new FrameOffsetForwarder(); + frameOffsetForwarder.start(); + const applyFrameOffset = frameOffsetForwarder.applyOffset.bind(frameOffsetForwarder); + popup = new PopupProxy(popupId, 0, null, frameId, url, applyFrameOffset); await popup.prepare(); } else if (proxy) { popup = new PopupProxy(null, depth + 1, id, parentFrameId, url); await popup.prepare(); } else { - window._frameOffsetForwarder = new FrameOffsetForwarder(); + const frameOffsetForwarder = new FrameOffsetForwarder(); + frameOffsetForwarder.start(); + const popupHost = new PopupProxyHost(); await popupHost.prepare(); diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index d6fe7af4..c160b9e3 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -53,7 +53,7 @@ class Frontend extends TextScanner { this._runtimeMessageHandlers = new Map([ ['popupSetVisibleOverride', ({visible}) => { this.popup.setVisibleOverride(visible); }], - ['rootPopupInformationGet', () => { this.popup.broadcastRootPopupInformation(); }] + ['rootPopupRequestInformationBroadcast', () => { this.popup.broadcastRootPopupInformation(); }] ]); } diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 73148eee..a25f9183 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -21,7 +21,7 @@ */ class PopupProxy { - constructor(id, depth, parentId, parentFrameId, url, applyFrameOffset=async (x, y) => [x, y]) { + constructor(id, depth, parentId, parentFrameId, url, applyFrameOffset=null) { this._parentId = parentId; this._parentFrameId = parentFrameId; this._id = id; @@ -81,7 +81,7 @@ class PopupProxy { } async containsPoint(x, y) { - if (this._depth === 0) { + if (this._applyFrameOffset !== null) { [x, y] = await this._applyFrameOffset(x, y); } return await this._invokeHostApi('containsPoint', {id: this._id, x, y}); @@ -89,7 +89,7 @@ class PopupProxy { async showContent(elementRect, writingMode, type=null, details=null) { let {x, y, width, height} = elementRect; - if (this._depth === 0) { + if (this._applyFrameOffset !== null) { [x, y] = await this._applyFrameOffset(x, y); } elementRect = {x, y, width, height}; diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 4c979911..47e32963 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -368,7 +368,6 @@ class Popup { chrome.runtime.onMessage.removeListener(runtimeMessageCallback); callback(); resolve(); - return false; } }; chrome.runtime.onMessage.addListener(runtimeMessageCallback); -- cgit v1.2.3 From 9f9ea1d5fb9f383992523a2a9a8a02259ced838e Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 22 Mar 2020 14:11:43 +0200 Subject: throttle frame offset getting --- ext/fg/js/frame-offset-forwarder.js | 4 ++-- ext/fg/js/frontend-initialize.js | 4 ++-- ext/fg/js/popup-proxy.js | 46 ++++++++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 10 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/frame-offset-forwarder.js b/ext/fg/js/frame-offset-forwarder.js index 38fc0b03..c32c2ec1 100644 --- a/ext/fg/js/frame-offset-forwarder.js +++ b/ext/fg/js/frame-offset-forwarder.js @@ -41,7 +41,7 @@ class FrameOffsetForwarder { this._started = true; } - async applyOffset(x, y) { + async getOffset() { const uniqueId = yomichan.generateId(16); const frameOffsetPromise = yomichan.getTemporaryListenerResult( @@ -58,7 +58,7 @@ class FrameOffsetForwarder { action: 'getFrameOffset', params: { uniqueId, - offset: [x, y] + offset: [0, 0] } }, '*'); diff --git a/ext/fg/js/frontend-initialize.js b/ext/fg/js/frontend-initialize.js index 97e315b5..2f86f5c8 100644 --- a/ext/fg/js/frontend-initialize.js +++ b/ext/fg/js/frontend-initialize.js @@ -45,9 +45,9 @@ async function main() { const frameOffsetForwarder = new FrameOffsetForwarder(); frameOffsetForwarder.start(); - const applyFrameOffset = frameOffsetForwarder.applyOffset.bind(frameOffsetForwarder); + const getFrameOffset = frameOffsetForwarder.getOffset.bind(frameOffsetForwarder); - popup = new PopupProxy(popupId, 0, null, frameId, url, applyFrameOffset); + popup = new PopupProxy(popupId, 0, null, frameId, url, getFrameOffset); await popup.prepare(); } else if (proxy) { popup = new PopupProxy(null, depth + 1, id, parentFrameId, url); diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index a25f9183..0cd5bbad 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -21,14 +21,18 @@ */ class PopupProxy { - constructor(id, depth, parentId, parentFrameId, url, applyFrameOffset=null) { + constructor(id, depth, parentId, parentFrameId, url, getFrameOffset=null) { this._parentId = parentId; this._parentFrameId = parentFrameId; this._id = id; this._depth = depth; this._url = url; this._apiSender = new FrontendApiSender(); - this._applyFrameOffset = applyFrameOffset; + this._getFrameOffset = getFrameOffset; + + this._frameOffset = null; + this._frameOffsetPromise = null; + this._frameOffsetUpdatedAt = null; } // Public properties @@ -81,16 +85,18 @@ class PopupProxy { } async containsPoint(x, y) { - if (this._applyFrameOffset !== null) { - [x, y] = await this._applyFrameOffset(x, y); + if (this._getFrameOffset !== null) { + await this._updateFrameOffset(); + [x, y] = this._applyFrameOffset(x, y); } return await this._invokeHostApi('containsPoint', {id: this._id, x, y}); } async showContent(elementRect, writingMode, type=null, details=null) { let {x, y, width, height} = elementRect; - if (this._applyFrameOffset !== null) { - [x, y] = await this._applyFrameOffset(x, y); + if (this._getFrameOffset !== null) { + await this._updateFrameOffset(); + [x, y] = this._applyFrameOffset(x, y); } elementRect = {x, y, width, height}; return await this._invokeHostApi('showContent', {id: this._id, elementRect, writingMode, type, details}); @@ -116,4 +122,32 @@ class PopupProxy { } return this._apiSender.invoke(action, params, `popup-proxy-host#${this._parentFrameId}`); } + + async _updateFrameOffset() { + const firstRun = this._frameOffsetUpdatedAt === null; + const expired = firstRun || this._frameOffsetUpdatedAt < Date.now() - 1000; + if (this._frameOffsetPromise === null && !expired) { return; } + + if (this._frameOffsetPromise !== null) { + await this._frameOffsetPromise; + return; + } + + if (firstRun) { + this._frameOffsetPromise = this._getFrameOffset(); + this._frameOffset = await this._frameOffsetPromise; + this._frameOffsetPromise = null; + this._frameOffsetUpdatedAt = Date.now(); + } else { + this._getFrameOffset().then((offset) => { + this._frameOffset = offset; + this._frameOffsetUpdatedAt = Date.now(); + }); + } + } + + _applyFrameOffset(x, y) { + const [offsetX, offsetY] = this._frameOffset; + return [x + offsetX, y + offsetY]; + } } -- cgit v1.2.3 From 7928c5d71324b3eebece7e2a26e9783e139066d5 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 22 Mar 2020 14:39:07 +0200 Subject: error handling --- ext/fg/js/popup-proxy.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 0cd5bbad..fd07ee46 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -129,19 +129,29 @@ class PopupProxy { if (this._frameOffsetPromise === null && !expired) { return; } if (this._frameOffsetPromise !== null) { - await this._frameOffsetPromise; + if (firstRun) { + await this._frameOffsetPromise; + } return; } + this._frameOffsetPromise = this._getFrameOffset(); if (firstRun) { - this._frameOffsetPromise = this._getFrameOffset(); - this._frameOffset = await this._frameOffsetPromise; + try { + this._frameOffset = await this._frameOffsetPromise; + this._frameOffsetUpdatedAt = Date.now(); + } catch (e) { + console.error(e); + } this._frameOffsetPromise = null; - this._frameOffsetUpdatedAt = Date.now(); } else { - this._getFrameOffset().then((offset) => { + this._frameOffsetPromise.then((offset) => { this._frameOffset = offset; this._frameOffsetUpdatedAt = Date.now(); + this._frameOffsetPromise = null; + }, (e) => { + console.error(e); + this._frameOffsetPromise = null; }); } } -- cgit v1.2.3 From 559033f0a6c2c8c298bd305065e475f0b385cd17 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 4 Apr 2020 16:48:35 +0300 Subject: default to [0, 0] when sourceFrame is not found --- ext/fg/js/frame-offset-forwarder.js | 5 ++++- ext/fg/js/popup-proxy.js | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/frame-offset-forwarder.js b/ext/fg/js/frame-offset-forwarder.js index c32c2ec1..7b417b6e 100644 --- a/ext/fg/js/frame-offset-forwarder.js +++ b/ext/fg/js/frame-offset-forwarder.js @@ -80,7 +80,10 @@ class FrameOffsetForwarder { sourceFrame = frame; break; } - if (sourceFrame === null) { return; } + if (sourceFrame === null) { + this._forwardFrameOffsetOrigin(null, uniqueId); + return; + } const [forwardedX, forwardedY] = offset; const {x, y} = sourceFrame.getBoundingClientRect(); diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index fd07ee46..67b0b2c6 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -138,7 +138,8 @@ class PopupProxy { this._frameOffsetPromise = this._getFrameOffset(); if (firstRun) { try { - this._frameOffset = await this._frameOffsetPromise; + const offset = await this._frameOffsetPromise; + this._frameOffset = offset !== null ? offset : [0, 0]; this._frameOffsetUpdatedAt = Date.now(); } catch (e) { console.error(e); @@ -146,7 +147,7 @@ class PopupProxy { this._frameOffsetPromise = null; } else { this._frameOffsetPromise.then((offset) => { - this._frameOffset = offset; + this._frameOffset = offset !== null ? offset : [0, 0]; this._frameOffsetUpdatedAt = Date.now(); this._frameOffsetPromise = null; }, (e) => { -- cgit v1.2.3 From e4fc53480f36b56abba0ab1cb20f6aad7bf4a004 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 4 Apr 2020 17:32:58 +0300 Subject: move broadcastRootPopupInformation to Frontend --- ext/fg/js/frontend.js | 11 +++++++++-- ext/fg/js/popup-proxy.js | 4 ---- ext/fg/js/popup.js | 11 ++++------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index c160b9e3..4e9d474c 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -18,6 +18,7 @@ /* global * TextScanner + * apiForward * apiGetZoom * apiKanjiFind * apiOptionsGet @@ -53,7 +54,7 @@ class Frontend extends TextScanner { this._runtimeMessageHandlers = new Map([ ['popupSetVisibleOverride', ({visible}) => { this.popup.setVisibleOverride(visible); }], - ['rootPopupRequestInformationBroadcast', () => { this.popup.broadcastRootPopupInformation(); }] + ['rootPopupRequestInformationBroadcast', () => { this._broadcastRootPopupInformation(); }] ]); } @@ -77,7 +78,7 @@ class Frontend extends TextScanner { chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); this._updateContentScale(); - this.popup.broadcastRootPopupInformation(); + this._broadcastRootPopupInformation(); } catch (e) { this.onError(e); } @@ -257,6 +258,12 @@ class Frontend extends TextScanner { this._updatePopupPosition(); } + _broadcastRootPopupInformation() { + if (!this.popup.isProxy() && this.popup.depth === 0) { + apiForward('rootPopupInformation', {popupId: this.popup.id, frameId: this.popup.frameId}); + } + } + async _updatePopupPosition() { const textSource = this.getCurrentTextSource(); if (textSource !== null && await this.popup.isVisible()) { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 67b0b2c6..cb264af2 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -64,10 +64,6 @@ class PopupProxy { return true; } - broadcastRootPopupInformation() { - // NOP - } - async setOptions(options) { return await this._invokeHostApi('setOptions', {id: this._id, options}); } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index fb3e56b4..60dc16dd 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -17,7 +17,6 @@ */ /* global - * apiForward * apiGetMessageToken * apiInjectStylesheet */ @@ -69,6 +68,10 @@ class Popup { return this._depth; } + get frameId() { + return this._frameId; + } + get url() { return window.location.href; } @@ -79,12 +82,6 @@ class Popup { return false; } - broadcastRootPopupInformation() { - if (this._depth === 0) { - apiForward('rootPopupInformation', {popupId: this._id, frameId: this._frameId}); - } - } - async setOptions(options) { this._options = options; this.updateTheme(); -- cgit v1.2.3 From 0d76cef43437fda336a3314dc62db1388537042f Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sat, 4 Apr 2020 17:39:26 +0300 Subject: give a name to a timeout --- ext/fg/js/popup-proxy.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index cb264af2..7405b552 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -121,7 +121,7 @@ class PopupProxy { async _updateFrameOffset() { const firstRun = this._frameOffsetUpdatedAt === null; - const expired = firstRun || this._frameOffsetUpdatedAt < Date.now() - 1000; + const expired = firstRun || this._frameOffsetUpdatedAt < Date.now() - PopupProxy._frameOffsetExpireTimeout; if (this._frameOffsetPromise === null && !expired) { return; } if (this._frameOffsetPromise !== null) { @@ -158,3 +158,5 @@ class PopupProxy { return [x + offsetX, y + offsetY]; } } + +PopupProxy._frameOffsetExpireTimeout = 1000; -- cgit v1.2.3 From abd056e5637be5cca3033296843dd442593c73e7 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 5 Apr 2020 15:32:57 +0300 Subject: reduce code duplication --- ext/fg/js/popup-proxy.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 7405b552..f1618c9f 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -132,24 +132,26 @@ class PopupProxy { } this._frameOffsetPromise = this._getFrameOffset(); + + const handleOffset = (offset) => { + this._frameOffset = offset !== null ? offset : [0, 0]; + this._frameOffsetUpdatedAt = Date.now(); + this._frameOffsetPromise = null; + }; + + const handleError = (e) => { + console.error(e); + this._frameOffsetPromise = null; + }; + if (firstRun) { try { - const offset = await this._frameOffsetPromise; - this._frameOffset = offset !== null ? offset : [0, 0]; - this._frameOffsetUpdatedAt = Date.now(); + handleOffset(await this._frameOffsetPromise); } catch (e) { - console.error(e); + handleError(e); } - this._frameOffsetPromise = null; } else { - this._frameOffsetPromise.then((offset) => { - this._frameOffset = offset !== null ? offset : [0, 0]; - this._frameOffsetUpdatedAt = Date.now(); - this._frameOffsetPromise = null; - }, (e) => { - console.error(e); - this._frameOffsetPromise = null; - }); + this._frameOffsetPromise.then(handleOffset, handleError); } } -- cgit v1.2.3 From aea7c590d1b381786978cd7871aed545be96ce34 Mon Sep 17 00:00:00 2001 From: siikamiika Date: Sun, 5 Apr 2020 19:21:06 +0300 Subject: refactor _updateFrameOffset --- ext/fg/js/popup-proxy.js | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) (limited to 'ext/fg/js/popup-proxy.js') diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index f1618c9f..966198a9 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -120,8 +120,9 @@ class PopupProxy { } async _updateFrameOffset() { + const now = Date.now(); const firstRun = this._frameOffsetUpdatedAt === null; - const expired = firstRun || this._frameOffsetUpdatedAt < Date.now() - PopupProxy._frameOffsetExpireTimeout; + const expired = firstRun || this._frameOffsetUpdatedAt < now - PopupProxy._frameOffsetExpireTimeout; if (this._frameOffsetPromise === null && !expired) { return; } if (this._frameOffsetPromise !== null) { @@ -131,27 +132,22 @@ class PopupProxy { return; } - this._frameOffsetPromise = this._getFrameOffset(); + const promise = this._updateFrameOffsetInner(now); + if (firstRun) { + await promise; + } + } - const handleOffset = (offset) => { + async _updateFrameOffsetInner(now) { + this._frameOffsetPromise = this._getFrameOffset(); + try { + const offset = await this._frameOffsetPromise; this._frameOffset = offset !== null ? offset : [0, 0]; - this._frameOffsetUpdatedAt = Date.now(); + this._frameOffsetUpdatedAt = now; + } catch (e) { + logError(e); + } finally { this._frameOffsetPromise = null; - }; - - const handleError = (e) => { - console.error(e); - this._frameOffsetPromise = null; - }; - - if (firstRun) { - try { - handleOffset(await this._frameOffsetPromise); - } catch (e) { - handleError(e); - } - } else { - this._frameOffsetPromise.then(handleOffset, handleError); } } -- cgit v1.2.3