Popup API refactor (#732)

* Simplify how parent/child are set

* Remove unused public frameId property

* Change use of getFrame

* Simplify parent access

* Use property for the container

* Remove isProxy

* Public function API parity

* Public property API parity
This commit is contained in:
toasted-nutbread 2020-08-15 17:27:03 -04:00 committed by GitHub
parent a9b16bd937
commit d5865db457
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 100 additions and 55 deletions

View File

@ -347,7 +347,13 @@ class Frontend {
}
_ignoreElements() {
return this._popup === null || this._popup.isProxy() ? [] : [this._popup.getContainer()];
if (this._popup !== null) {
const container = this._popup.container;
if (container !== null) {
return [container];
}
}
return [];
}
async _ignorePoint(x, y) {
@ -526,7 +532,6 @@ class Frontend {
_broadcastRootPopupInformation() {
if (
this._popup !== null &&
!this._popup.isProxy() &&
this._depth === 0 &&
this._frameId === 0
) {

View File

@ -30,16 +30,19 @@ class PopupFactory {
prepare() {
api.crossFrame.registerHandlers([
['getOrCreatePopup', {async: false, handler: this._onApiGetOrCreatePopup.bind(this)}],
['setOptionsContext', {async: true, handler: this._onApiSetOptionsContext.bind(this)}],
['hide', {async: false, handler: this._onApiHide.bind(this)}],
['isVisible', {async: true, handler: this._onApiIsVisibleAsync.bind(this)}],
['setVisibleOverride', {async: true, handler: this._onApiSetVisibleOverride.bind(this)}],
['containsPoint', {async: true, handler: this._onApiContainsPoint.bind(this)}],
['showContent', {async: true, handler: this._onApiShowContent.bind(this)}],
['setCustomCss', {async: false, handler: this._onApiSetCustomCss.bind(this)}],
['clearAutoPlayTimer', {async: false, handler: this._onApiClearAutoPlayTimer.bind(this)}],
['setContentScale', {async: false, handler: this._onApiSetContentScale.bind(this)}]
['getOrCreatePopup', {async: false, handler: this._onApiGetOrCreatePopup.bind(this)}],
['setOptionsContext', {async: true, handler: this._onApiSetOptionsContext.bind(this)}],
['hide', {async: false, handler: this._onApiHide.bind(this)}],
['isVisible', {async: true, handler: this._onApiIsVisibleAsync.bind(this)}],
['setVisibleOverride', {async: true, handler: this._onApiSetVisibleOverride.bind(this)}],
['containsPoint', {async: true, handler: this._onApiContainsPoint.bind(this)}],
['showContent', {async: true, handler: this._onApiShowContent.bind(this)}],
['setCustomCss', {async: false, handler: this._onApiSetCustomCss.bind(this)}],
['clearAutoPlayTimer', {async: false, handler: this._onApiClearAutoPlayTimer.bind(this)}],
['setContentScale', {async: false, handler: this._onApiSetContentScale.bind(this)}],
['updateTheme', {async: false, handler: this._onApiUpdateTheme.bind(this)}],
['setCustomOuterCss', {async: false, handler: this._onApiSetCustomOuterCss.bind(this)}],
['setChildrenSupported', {async: false, handler: this._onApiSetChildrenSupported.bind(this)}]
]);
}
@ -82,7 +85,11 @@ class PopupFactory {
}
const popup = new Popup(id, depth, this._frameId, ownerFrameId);
if (parent !== null) {
popup.setParent(parent);
if (parent.child !== null) {
throw new Error('Parent popup already has a child');
}
popup.parent = parent;
parent.child = popup;
}
this._popups.set(id, popup);
popup.prepare();
@ -151,6 +158,21 @@ class PopupFactory {
return popup.setContentScale(scale);
}
_onApiUpdateTheme({id}) {
const popup = this._getPopup(id);
return popup.updateTheme();
}
_onApiSetCustomOuterCss({id, css, useWebExtensionApi}) {
const popup = this._getPopup(id);
return popup.setCustomOuterCss(css, useWebExtensionApi);
}
_onApiSetChildrenSupported({id, value}) {
const popup = this._getPopup(id);
return popup.setChildrenSupported(value);
}
// Private functions
_getPopup(id) {
@ -167,8 +189,9 @@ class PopupFactory {
}
_convertPopupPointToRootPagePoint(popup, x, y) {
if (popup.parent !== null) {
const popupRect = popup.parent.getFrameRect();
const parent = popup.parent;
if (parent !== null) {
const popupRect = parent.getFrameRect();
x += popupRect.x;
y += popupRect.y;
}
@ -176,6 +199,7 @@ class PopupFactory {
}
_popupCanShow(popup) {
return popup.parent === null || popup.parent.isVisibleSync();
const parent = popup.parent;
return parent === null || parent.isVisibleSync();
}
}

View File

@ -45,10 +45,30 @@ class PopupProxy extends EventDispatcher {
return null;
}
set parent(value) {
throw new Error('Not supported on PopupProxy');
}
get child() {
return null;
}
set child(value) {
throw new Error('Not supported on PopupProxy');
}
get depth() {
return this._depth;
}
get frameContentWindow() {
return null;
}
get container() {
return null;
}
// Public functions
async prepare() {
@ -56,10 +76,6 @@ class PopupProxy extends EventDispatcher {
this._id = id;
}
isProxy() {
return true;
}
setOptionsContext(optionsContext, source) {
return this._invokeSafe('setOptionsContext', {id: this._id, optionsContext, source});
}
@ -109,6 +125,26 @@ class PopupProxy extends EventDispatcher {
return this._invokeSafe('setContentScale', {id: this._id, scale});
}
isVisibleSync() {
throw new Error('Not supported on PopupProxy');
}
updateTheme() {
return this._invokeSafe('updateTheme', {id: this._id});
}
async setCustomOuterCss(css, useWebExtensionApi) {
return this._invokeSafe('updateTheme', {id: this._id, css, useWebExtensionApi});
}
setChildrenSupported(value) {
return this._invokeSafe('updateTheme', {id: this._id, value});
}
getFrameRect() {
return new DOMRect(0, 0, 0, 0);
}
// Private
_invoke(action, params={}) {

View File

@ -64,16 +64,28 @@ class Popup {
return this._parent;
}
set parent(value) {
this._parent = value;
}
get child() {
return this._child;
}
set child(value) {
this._child = value;
}
get depth() {
return this._depth;
}
get frameId() {
return this._frameId;
get frameContentWindow() {
return this._frame.contentWindow;
}
get container() {
return this._container;
}
// Public functions
@ -86,10 +98,6 @@ class Popup {
yomichan.on('extensionUnloaded', this._onExtensionUnloaded.bind(this));
}
isProxy() {
return false;
}
async setOptionsContext(optionsContext, source) {
this._optionsContext = optionsContext;
this._previousOptionsContextSource = source;
@ -163,26 +171,6 @@ class Popup {
this._invokeSafe('setContentScale', {scale});
}
// Popup-only public functions
setParent(parent) {
if (parent === null) {
throw new Error('Cannot set popup parent to null');
}
if (this._parent !== null) {
throw new Error('Popup already has a parent');
}
parent.setChild(this);
this._parent = parent;
}
setChild(popup) {
if (this._child !== null) {
throw new Error('Popup already has a child');
}
this._child = popup;
}
isVisibleSync() {
return (this._visibleOverride !== null ? this._visibleOverride : this._visible);
}
@ -205,18 +193,10 @@ class Popup {
this._childrenSupported = value;
}
getFrame() {
return this._frame;
}
getFrameRect() {
return this._frame.getBoundingClientRect();
}
getContainer() {
return this._container;
}
// Private functions
_inject() {
@ -418,7 +398,7 @@ class Popup {
_focusParent() {
if (this._parent !== null) {
// Chrome doesn't like focusing iframe without contentWindow.
const contentWindow = this._parent.getFrame().contentWindow;
const contentWindow = this._parent.frameContentWindow;
if (contentWindow !== null) {
contentWindow.focus();
}