Update how popups are created

This commit is contained in:
toasted-nutbread 2020-02-16 17:27:55 -05:00
parent 5d3c13ee98
commit dcd243c9e9
5 changed files with 62 additions and 29 deletions

View File

@ -50,7 +50,7 @@ class SettingsPopupPreview {
const popupHost = new PopupProxyHost();
await popupHost.prepare();
const popup = popupHost.createPopup(null, 0);
const popup = popupHost.getOrCreatePopup();
popup.setChildrenSupported(false);
this.frontend = new Frontend(popup);

View File

@ -22,13 +22,16 @@ async function main() {
const data = window.frontendInitializationData || {};
const {id, depth=0, parentFrameId, ignoreNodes, url, proxy=false} = data;
let popupHost = null;
if (!proxy) {
popupHost = new PopupProxyHost();
let popup;
if (proxy) {
popup = new PopupProxy(null, depth + 1, id, parentFrameId, url);
} else {
const popupHost = new PopupProxyHost();
await popupHost.prepare();
popup = popupHost.getOrCreatePopup();
}
const popup = proxy ? new PopupProxy(depth + 1, id, parentFrameId, url) : popupHost.createPopup(null, depth);
const frontend = new Frontend(popup, ignoreNodes);
await frontend.prepare();
}

View File

@ -34,7 +34,7 @@ class PopupProxyHost {
if (typeof frameId !== 'number') { return; }
this._apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([
['createNestedPopup', ({parentId}) => this._onApiCreateNestedPopup(parentId)],
['getOrCreatePopup', ({id, parentId}) => this._onApiGetOrCreatePopup(id, parentId)],
['setOptions', ({id, options}) => this._onApiSetOptions(id, options)],
['hide', ({id, changeFocus}) => this._onApiHide(id, changeFocus)],
['isVisible', ({id}) => this._onApiIsVisibleAsync(id)],
@ -47,14 +47,51 @@ class PopupProxyHost {
]));
}
createPopup(parentId, depth) {
return this._createPopupInternal(parentId, depth).popup;
getOrCreatePopup(id=null, parentId=null) {
// Find by existing id
if (id !== null) {
const popup = this._popups.get(id);
if (typeof popup !== 'undefined') {
return popup;
}
}
// Find by existing parent id
let parent = null;
if (parentId !== null) {
parent = this._popups.get(parentId);
if (typeof parent !== 'undefined') {
const popup = parent.child;
if (popup !== null) {
return popup;
}
} else {
parent = null;
}
}
// New unique id
if (id === null) {
id = this._nextId++;
}
// Create new popup
const depth = (parent !== null ? parent.depth + 1 : 0);
const popup = new Popup(id, depth, this._frameIdPromise);
if (parent !== null) {
popup.setParent(parent);
}
this._popups.set(id, popup);
return popup;
}
// Message handlers
async _onApiCreateNestedPopup(parentId) {
return this._createPopupInternal(parentId, 0).id;
async _onApiGetOrCreatePopup(id, parentId) {
const popup = this.getOrCreatePopup(id, parentId);
return {
id: popup.id
};
}
async _onApiSetOptions(id, options) {
@ -106,25 +143,10 @@ class PopupProxyHost {
// Private functions
_createPopupInternal(parentId, depth) {
const parent = (typeof parentId === 'string' && this._popups.has(parentId) ? this._popups.get(parentId) : null);
const id = `${this._nextId}`;
if (parent !== null) {
depth = parent.depth + 1;
}
++this._nextId;
const popup = new Popup(id, depth, this._frameIdPromise);
if (parent !== null) {
popup.setParent(parent);
}
this._popups.set(id, popup);
return {popup, id};
}
_getPopup(id) {
const popup = this._popups.get(id);
if (typeof popup === 'undefined') {
throw new Error('Invalid popup ID');
throw new Error(`Invalid popup ID ${id}`);
}
return popup;
}

View File

@ -19,10 +19,10 @@
/*global FrontendApiSender*/
class PopupProxy {
constructor(depth, parentId, parentFrameId, url) {
constructor(id, depth, parentId, parentFrameId, url) {
this._parentId = parentId;
this._parentFrameId = parentFrameId;
this._id = null;
this._id = id;
this._idPromise = null;
this._depth = depth;
this._url = url;
@ -113,7 +113,7 @@ class PopupProxy {
}
async _getPopupIdAsync() {
const id = await this._invokeHostApi('createNestedPopup', {parentId: this._parentId});
const {id} = await this._invokeHostApi('getOrCreatePopup', {id: this._id, parentId: this._parentId});
this._id = id;
return id;
}

View File

@ -49,10 +49,18 @@ class Popup {
// Public properties
get id() {
return this._id;
}
get parent() {
return this._parent;
}
get child() {
return this._child;
}
get depth() {
return this._depth;
}