aboutsummaryrefslogtreecommitdiff
path: root/ext/fg/js/popup-proxy-host.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/fg/js/popup-proxy-host.js')
-rw-r--r--ext/fg/js/popup-proxy-host.js161
1 files changed, 81 insertions, 80 deletions
diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js
index b2f18b97..c4f0c6ff 100644
--- a/ext/fg/js/popup-proxy-host.js
+++ b/ext/fg/js/popup-proxy-host.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2019 Alex Yatskov <alex@foosoft.net>
+ * Copyright (C) 2019-2020 Alex Yatskov <alex@foosoft.net>
* Author: Alex Yatskov <alex@foosoft.net>
*
* This program is free software: you can redistribute it and/or modify
@@ -13,126 +13,127 @@
* 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 <http://www.gnu.org/licenses/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class PopupProxyHost {
constructor() {
- this.popups = {};
- this.nextId = 0;
- this.apiReceiver = null;
- this.frameIdPromise = null;
+ this._popups = new Map();
+ this._nextId = 0;
+ this._apiReceiver = null;
+ this._frameIdPromise = null;
}
- static create() {
- const popupProxyHost = new PopupProxyHost();
- popupProxyHost.prepare();
- return popupProxyHost;
- }
+ // Public functions
async prepare() {
- this.frameIdPromise = apiFrameInformationGet();
- const {frameId} = await this.frameIdPromise;
+ this._frameIdPromise = apiFrameInformationGet();
+ const {frameId} = await this._frameIdPromise;
if (typeof frameId !== 'number') { return; }
- this.apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, {
- createNestedPopup: ({parentId}) => this.createNestedPopup(parentId),
- setOptions: ({id, options}) => this.setOptions(id, options),
- hide: ({id, changeFocus}) => this.hide(id, changeFocus),
- isVisibleAsync: ({id}) => this.isVisibleAsync(id),
- setVisibleOverride: ({id, visible}) => this.setVisibleOverride(id, visible),
- containsPoint: ({id, x, y}) => this.containsPoint(id, x, y),
- showContent: ({id, elementRect, writingMode, type, details}) => this.showContent(id, elementRect, writingMode, type, details),
- setCustomCss: ({id, css}) => this.setCustomCss(id, css),
- clearAutoPlayTimer: ({id}) => this.clearAutoPlayTimer(id)
- });
+ this._apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${frameId}`, new Map([
+ ['createNestedPopup', ({parentId}) => this._onApiCreateNestedPopup(parentId)],
+ ['setOptions', ({id, options}) => this._onApiSetOptions(id, options)],
+ ['hide', ({id, changeFocus}) => this._onApiHide(id, changeFocus)],
+ ['isVisible', ({id}) => this._onApiIsVisibleAsync(id)],
+ ['setVisibleOverride', ({id, visible}) => this._onApiSetVisibleOverride(id, visible)],
+ ['containsPoint', ({id, x, y}) => this._onApiContainsPoint(id, x, y)],
+ ['showContent', ({id, elementRect, writingMode, type, details}) => this._onApiShowContent(id, elementRect, writingMode, type, details)],
+ ['setCustomCss', ({id, css}) => this._onApiSetCustomCss(id, css)],
+ ['clearAutoPlayTimer', ({id}) => this._onApiClearAutoPlayTimer(id)]
+ ]));
}
createPopup(parentId, depth) {
- const parent = (typeof parentId === 'string' && hasOwn(this.popups, parentId) ? this.popups[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.parent = parent;
- parent.child = popup;
- }
- this.popups[id] = popup;
- return popup;
- }
-
- async createNestedPopup(parentId) {
- return this.createPopup(parentId, 0).id;
+ return this._createPopupInternal(parentId, depth).popup;
}
- getPopup(id) {
- if (!hasOwn(this.popups, id)) {
- throw new Error('Invalid popup ID');
- }
-
- return this.popups[id];
- }
+ // Message handlers
- jsonRectToDOMRect(popup, jsonRect) {
- let x = jsonRect.x;
- let y = jsonRect.y;
- if (popup.parent !== null) {
- const popupRect = popup.parent.container.getBoundingClientRect();
- x += popupRect.x;
- y += popupRect.y;
- }
- return new DOMRect(x, y, jsonRect.width, jsonRect.height);
+ async _onApiCreateNestedPopup(parentId) {
+ return this._createPopupInternal(parentId, 0).id;
}
- async setOptions(id, options) {
- const popup = this.getPopup(id);
+ async _onApiSetOptions(id, options) {
+ const popup = this._getPopup(id);
return await popup.setOptions(options);
}
- async hide(id, changeFocus) {
- const popup = this.getPopup(id);
+ async _onApiHide(id, changeFocus) {
+ const popup = this._getPopup(id);
return popup.hide(changeFocus);
}
- async isVisibleAsync(id) {
- const popup = this.getPopup(id);
- return await popup.isVisibleAsync();
+ async _onApiIsVisibleAsync(id) {
+ const popup = this._getPopup(id);
+ return await popup.isVisible();
}
- async setVisibleOverride(id, visible) {
- const popup = this.getPopup(id);
+ async _onApiSetVisibleOverride(id, visible) {
+ const popup = this._getPopup(id);
return await popup.setVisibleOverride(visible);
}
- async containsPoint(id, x, y) {
- const popup = this.getPopup(id);
+ async _onApiContainsPoint(id, x, y) {
+ const popup = this._getPopup(id);
return await popup.containsPoint(x, y);
}
- async showContent(id, elementRect, writingMode, type, details) {
- const popup = this.getPopup(id);
- elementRect = this.jsonRectToDOMRect(popup, elementRect);
- if (!PopupProxyHost.popupCanShow(popup)) { return Promise.resolve(false); }
+ async _onApiShowContent(id, elementRect, writingMode, type, details) {
+ const popup = this._getPopup(id);
+ elementRect = PopupProxyHost._convertJsonRectToDOMRect(popup, elementRect);
+ if (!PopupProxyHost._popupCanShow(popup)) { return; }
return await popup.showContent(elementRect, writingMode, type, details);
}
- async setCustomCss(id, css) {
- const popup = this.getPopup(id);
+ async _onApiSetCustomCss(id, css) {
+ const popup = this._getPopup(id);
return popup.setCustomCss(css);
}
- async clearAutoPlayTimer(id) {
- const popup = this.getPopup(id);
+ async _onApiClearAutoPlayTimer(id) {
+ const popup = this._getPopup(id);
return popup.clearAutoPlayTimer();
}
- static popupCanShow(popup) {
- return popup.parent === null || popup.parent.isVisible();
+ // 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};
}
-}
-PopupProxyHost.instance = PopupProxyHost.create();
+ _getPopup(id) {
+ const popup = this._popups.get(id);
+ if (typeof popup === 'undefined') {
+ throw new Error('Invalid popup ID');
+ }
+ return popup;
+ }
+
+ static _convertJsonRectToDOMRect(popup, jsonRect) {
+ let x = jsonRect.x;
+ let y = jsonRect.y;
+ if (popup.parent !== null) {
+ const popupRect = popup.parent.getContainerRect();
+ x += popupRect.x;
+ y += popupRect.y;
+ }
+ return new DOMRect(x, y, jsonRect.width, jsonRect.height);
+ }
+
+ static _popupCanShow(popup) {
+ return popup.parent === null || popup.parent.isVisibleSync();
+ }
+}