Various updates to FrameOffsetForwarder (#657)

* Remove bindings

* Fast exit if same window

* Simplify selector

* Rename functions, reuse _getFrameOffsetParent

* Update message style

* Send reply message to a specific frame
This commit is contained in:
toasted-nutbread 2020-07-10 22:13:11 -04:00 committed by GitHub
parent 59c224d99d
commit 964f011409
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 25 deletions

View File

@ -20,20 +20,14 @@
*/ */
class FrameOffsetForwarder { class FrameOffsetForwarder {
constructor() { constructor(frameId) {
this._frameId = frameId;
this._isPrepared = false; this._isPrepared = false;
this._cacheMaxSize = 1000; this._cacheMaxSize = 1000;
this._frameCache = new Set(); this._frameCache = new Set();
this._unreachableContentWindowCache = new Set(); this._unreachableContentWindowCache = new Set();
this._forwardFrameOffset = (
window !== window.parent ?
this._forwardFrameOffsetParent.bind(this) :
this._forwardFrameOffsetOrigin.bind(this)
);
this._windowMessageHandlers = new Map([ this._windowMessageHandlers = new Map([
['getFrameOffset', ({offset, uniqueId}, e) => this._onGetFrameOffset(offset, uniqueId, e)] ['getFrameOffset', this._onMessageGetFrameOffset.bind(this)]
]); ]);
} }
@ -44,6 +38,10 @@ class FrameOffsetForwarder {
} }
async getOffset() { async getOffset() {
if (window === window.parent) {
return [0, 0];
}
const uniqueId = yomichan.generateId(16); const uniqueId = yomichan.generateId(16);
const frameOffsetPromise = yomichan.getTemporaryListenerResult( const frameOffsetPromise = yomichan.getTemporaryListenerResult(
@ -56,13 +54,7 @@ class FrameOffsetForwarder {
5000 5000
); );
window.parent.postMessage({ this._getFrameOffsetParent([0, 0], uniqueId, this._frameId);
action: 'getFrameOffset',
params: {
uniqueId,
offset: [0, 0]
}
}, '*');
const {offset} = await frameOffsetPromise; const {offset} = await frameOffsetPromise;
return offset; return offset;
@ -84,7 +76,7 @@ class FrameOffsetForwarder {
} }
} }
_onGetFrameOffset(offset, uniqueId, e) { _onMessageGetFrameOffset({offset, uniqueId, frameId}, e) {
let sourceFrame = null; let sourceFrame = null;
if (!this._unreachableContentWindowCache.has(e.source)) { if (!this._unreachableContentWindowCache.has(e.source)) {
sourceFrame = this._findFrameWithContentWindow(e.source); sourceFrame = this._findFrameWithContentWindow(e.source);
@ -92,7 +84,7 @@ class FrameOffsetForwarder {
if (sourceFrame === null) { if (sourceFrame === null) {
// closed shadow root etc. // closed shadow root etc.
this._addToCache(this._unreachableContentWindowCache, e.source); this._addToCache(this._unreachableContentWindowCache, e.source);
this._forwardFrameOffsetOrigin(null, uniqueId); this._replyFrameOffset(null, uniqueId, frameId);
return; return;
} }
@ -100,7 +92,11 @@ class FrameOffsetForwarder {
const {x, y} = sourceFrame.getBoundingClientRect(); const {x, y} = sourceFrame.getBoundingClientRect();
offset = [forwardedX + x, forwardedY + y]; offset = [forwardedX + x, forwardedY + y];
this._forwardFrameOffset(offset, uniqueId); if (window === window.parent) {
this._replyFrameOffset(offset, uniqueId, frameId);
} else {
this._getFrameOffsetParent(offset, uniqueId, frameId);
}
} }
_findFrameWithContentWindow(contentWindow) { _findFrameWithContentWindow(contentWindow) {
@ -148,7 +144,7 @@ class FrameOffsetForwarder {
} }
yield frameCache; yield frameCache;
// will contain duplicates, but frame elements are cheap to handle // will contain duplicates, but frame elements are cheap to handle
yield [...document.querySelectorAll('frame, iframe:not(.yomichan-float)')]; yield [...document.querySelectorAll('frame,iframe')];
yield [document.documentElement]; yield [document.documentElement];
} }
@ -164,11 +160,18 @@ class FrameOffsetForwarder {
cache.add(value); cache.add(value);
} }
_forwardFrameOffsetParent(offset, uniqueId) { _getFrameOffsetParent(offset, uniqueId, frameId) {
window.parent.postMessage({action: 'getFrameOffset', params: {offset, uniqueId}}, '*'); window.parent.postMessage({
action: 'getFrameOffset',
params: {
offset,
uniqueId,
frameId
}
}, '*');
} }
_forwardFrameOffsetOrigin(offset, uniqueId) { _replyFrameOffset(offset, uniqueId, frameId) {
api.broadcastTab('frameOffset', {offset, uniqueId}); api.sendMessageToFrame(frameId, 'frameOffset', {offset, uniqueId});
} }
} }

View File

@ -56,7 +56,7 @@ class Frontend {
this._isSearchPage = isSearchPage; this._isSearchPage = isSearchPage;
this._depth = depth; this._depth = depth;
this._frameId = frameId; this._frameId = frameId;
this._frameOffsetForwarder = new FrameOffsetForwarder(); this._frameOffsetForwarder = new FrameOffsetForwarder(frameId);
this._popupFactory = popupFactory; this._popupFactory = popupFactory;
this._allowRootFramePopupProxy = allowRootFramePopupProxy; this._allowRootFramePopupProxy = allowRootFramePopupProxy;
this._popupCache = new Map(); this._popupCache = new Map();