PopupProxy refactor (#609)

* Remove setDisabled member; replace with an event

* Pass frameOffsetForwarder directly to PopupProxy

* Replace .start with .prepare

* Make onMessage private

* Make message safer and handle unexpected inputs
This commit is contained in:
toasted-nutbread 2020-06-14 14:06:52 -04:00 committed by GitHub
parent 8d1a276a83
commit b612bd8b8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 24 deletions

View File

@ -49,9 +49,8 @@ async function createIframePopupProxy(frameOffsetForwarder, setDisabled) {
api.broadcastTab('rootPopupRequestInformationBroadcast'); api.broadcastTab('rootPopupRequestInformationBroadcast');
const {popupId, frameId: parentFrameId} = await rootPopupInformationPromise; const {popupId, frameId: parentFrameId} = await rootPopupInformationPromise;
const getFrameOffset = frameOffsetForwarder.getOffset.bind(frameOffsetForwarder); const popup = new PopupProxy(popupId, 0, null, parentFrameId, frameOffsetForwarder);
popup.on('offsetNotFound', setDisabled);
const popup = new PopupProxy(popupId, 0, null, parentFrameId, getFrameOffset, setDisabled);
await popup.prepare(); await popup.prepare();
return popup; return popup;
@ -115,7 +114,7 @@ async function createPopupProxy(depth, id, parentFrameId) {
if (!proxy && frameOffsetForwarder === null) { if (!proxy && frameOffsetForwarder === null) {
frameOffsetForwarder = new FrameOffsetForwarder(); frameOffsetForwarder = new FrameOffsetForwarder();
frameOffsetForwarder.start(); frameOffsetForwarder.prepare();
} }
let popup; let popup;

View File

@ -21,8 +21,7 @@
class FrameOffsetForwarder { class FrameOffsetForwarder {
constructor() { constructor() {
this._started = 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();
@ -38,10 +37,10 @@ class FrameOffsetForwarder {
]); ]);
} }
start() { prepare() {
if (this._started) { return; } if (this._isPrepared) { return; }
window.addEventListener('message', this.onMessage.bind(this), false); window.addEventListener('message', this._onMessage.bind(this), false);
this._started = true; this._isPrepared = true;
} }
async getOffset() { async getOffset() {
@ -69,11 +68,20 @@ class FrameOffsetForwarder {
return offset; return offset;
} }
onMessage(e) { // Private
const {action, params} = e.data;
_onMessage(event) {
const data = event.data;
if (data === null || typeof data !== 'object') { return; }
try {
const {action, params} = event.data;
const handler = this._windowMessageHandlers.get(action); const handler = this._windowMessageHandlers.get(action);
if (typeof handler !== 'function') { return; } if (typeof handler !== 'function') { return; }
handler(params, e); handler(params, event);
} catch (e) {
// NOP
}
} }
_onGetFrameOffset(offset, uniqueId, e) { _onGetFrameOffset(offset, uniqueId, e) {

View File

@ -19,14 +19,14 @@
* api * api
*/ */
class PopupProxy { class PopupProxy extends EventDispatcher {
constructor(id, depth, parentPopupId, parentFrameId, getFrameOffset=null, setDisabled=null) { constructor(id, depth, parentPopupId, parentFrameId, frameOffsetForwarder=null) {
super();
this._id = id; this._id = id;
this._depth = depth; this._depth = depth;
this._parentPopupId = parentPopupId; this._parentPopupId = parentPopupId;
this._parentFrameId = parentFrameId; this._parentFrameId = parentFrameId;
this._getFrameOffset = getFrameOffset; this._frameOffsetForwarder = frameOffsetForwarder;
this._setDisabled = setDisabled;
this._frameOffset = null; this._frameOffset = null;
this._frameOffsetPromise = null; this._frameOffsetPromise = null;
@ -75,7 +75,7 @@ class PopupProxy {
} }
async containsPoint(x, y) { async containsPoint(x, y) {
if (this._getFrameOffset !== null) { if (this._frameOffsetForwarder !== null) {
await this._updateFrameOffset(); await this._updateFrameOffset();
[x, y] = this._applyFrameOffset(x, y); [x, y] = this._applyFrameOffset(x, y);
} }
@ -84,7 +84,7 @@ class PopupProxy {
async showContent(elementRect, writingMode, type, details, context) { async showContent(elementRect, writingMode, type, details, context) {
let {x, y, width, height} = elementRect; let {x, y, width, height} = elementRect;
if (this._getFrameOffset !== null) { if (this._frameOffsetForwarder !== null) {
await this._updateFrameOffset(); await this._updateFrameOffset();
[x, y] = this._applyFrameOffset(x, y); [x, y] = this._applyFrameOffset(x, y);
} }
@ -134,12 +134,12 @@ class PopupProxy {
} }
async _updateFrameOffsetInner(now) { async _updateFrameOffsetInner(now) {
this._frameOffsetPromise = this._getFrameOffset(); this._frameOffsetPromise = this._frameOffsetForwarder.getOffset();
try { try {
const offset = await this._frameOffsetPromise; const offset = await this._frameOffsetPromise;
this._frameOffset = offset !== null ? offset : [0, 0]; this._frameOffset = offset !== null ? offset : [0, 0];
if (offset === null && this._setDisabled !== null) { if (offset === null) {
this._setDisabled(); this.trigger('offsetNotFound');
return; return;
} }
this._frameOffsetUpdatedAt = now; this._frameOffsetUpdatedAt = now;