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 {
constructor() {
constructor(frameId) {
this._frameId = frameId;
this._isPrepared = false;
this._cacheMaxSize = 1000;
this._frameCache = new Set();
this._unreachableContentWindowCache = new Set();
this._forwardFrameOffset = (
window !== window.parent ?
this._forwardFrameOffsetParent.bind(this) :
this._forwardFrameOffsetOrigin.bind(this)
);
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() {
if (window === window.parent) {
return [0, 0];
}
const uniqueId = yomichan.generateId(16);
const frameOffsetPromise = yomichan.getTemporaryListenerResult(
@ -56,13 +54,7 @@ class FrameOffsetForwarder {
5000
);
window.parent.postMessage({
action: 'getFrameOffset',
params: {
uniqueId,
offset: [0, 0]
}
}, '*');
this._getFrameOffsetParent([0, 0], uniqueId, this._frameId);
const {offset} = await frameOffsetPromise;
return offset;
@ -84,7 +76,7 @@ class FrameOffsetForwarder {
}
}
_onGetFrameOffset(offset, uniqueId, e) {
_onMessageGetFrameOffset({offset, uniqueId, frameId}, e) {
let sourceFrame = null;
if (!this._unreachableContentWindowCache.has(e.source)) {
sourceFrame = this._findFrameWithContentWindow(e.source);
@ -92,7 +84,7 @@ class FrameOffsetForwarder {
if (sourceFrame === null) {
// closed shadow root etc.
this._addToCache(this._unreachableContentWindowCache, e.source);
this._forwardFrameOffsetOrigin(null, uniqueId);
this._replyFrameOffset(null, uniqueId, frameId);
return;
}
@ -100,7 +92,11 @@ class FrameOffsetForwarder {
const {x, y} = sourceFrame.getBoundingClientRect();
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) {
@ -148,7 +144,7 @@ class FrameOffsetForwarder {
}
yield frameCache;
// 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];
}
@ -164,11 +160,18 @@ class FrameOffsetForwarder {
cache.add(value);
}
_forwardFrameOffsetParent(offset, uniqueId) {
window.parent.postMessage({action: 'getFrameOffset', params: {offset, uniqueId}}, '*');
_getFrameOffsetParent(offset, uniqueId, frameId) {
window.parent.postMessage({
action: 'getFrameOffset',
params: {
offset,
uniqueId,
frameId
}
}, '*');
}
_forwardFrameOffsetOrigin(offset, uniqueId) {
api.broadcastTab('frameOffset', {offset, uniqueId});
_replyFrameOffset(offset, uniqueId, frameId) {
api.sendMessageToFrame(frameId, 'frameOffset', {offset, uniqueId});
}
}

View File

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