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:
parent
a9b16bd937
commit
d5865db457
@ -347,7 +347,13 @@ class Frontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ignoreElements() {
|
_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) {
|
async _ignorePoint(x, y) {
|
||||||
@ -526,7 +532,6 @@ class Frontend {
|
|||||||
_broadcastRootPopupInformation() {
|
_broadcastRootPopupInformation() {
|
||||||
if (
|
if (
|
||||||
this._popup !== null &&
|
this._popup !== null &&
|
||||||
!this._popup.isProxy() &&
|
|
||||||
this._depth === 0 &&
|
this._depth === 0 &&
|
||||||
this._frameId === 0
|
this._frameId === 0
|
||||||
) {
|
) {
|
||||||
|
@ -30,16 +30,19 @@ class PopupFactory {
|
|||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
api.crossFrame.registerHandlers([
|
api.crossFrame.registerHandlers([
|
||||||
['getOrCreatePopup', {async: false, handler: this._onApiGetOrCreatePopup.bind(this)}],
|
['getOrCreatePopup', {async: false, handler: this._onApiGetOrCreatePopup.bind(this)}],
|
||||||
['setOptionsContext', {async: true, handler: this._onApiSetOptionsContext.bind(this)}],
|
['setOptionsContext', {async: true, handler: this._onApiSetOptionsContext.bind(this)}],
|
||||||
['hide', {async: false, handler: this._onApiHide.bind(this)}],
|
['hide', {async: false, handler: this._onApiHide.bind(this)}],
|
||||||
['isVisible', {async: true, handler: this._onApiIsVisibleAsync.bind(this)}],
|
['isVisible', {async: true, handler: this._onApiIsVisibleAsync.bind(this)}],
|
||||||
['setVisibleOverride', {async: true, handler: this._onApiSetVisibleOverride.bind(this)}],
|
['setVisibleOverride', {async: true, handler: this._onApiSetVisibleOverride.bind(this)}],
|
||||||
['containsPoint', {async: true, handler: this._onApiContainsPoint.bind(this)}],
|
['containsPoint', {async: true, handler: this._onApiContainsPoint.bind(this)}],
|
||||||
['showContent', {async: true, handler: this._onApiShowContent.bind(this)}],
|
['showContent', {async: true, handler: this._onApiShowContent.bind(this)}],
|
||||||
['setCustomCss', {async: false, handler: this._onApiSetCustomCss.bind(this)}],
|
['setCustomCss', {async: false, handler: this._onApiSetCustomCss.bind(this)}],
|
||||||
['clearAutoPlayTimer', {async: false, handler: this._onApiClearAutoPlayTimer.bind(this)}],
|
['clearAutoPlayTimer', {async: false, handler: this._onApiClearAutoPlayTimer.bind(this)}],
|
||||||
['setContentScale', {async: false, handler: this._onApiSetContentScale.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);
|
const popup = new Popup(id, depth, this._frameId, ownerFrameId);
|
||||||
if (parent !== null) {
|
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);
|
this._popups.set(id, popup);
|
||||||
popup.prepare();
|
popup.prepare();
|
||||||
@ -151,6 +158,21 @@ class PopupFactory {
|
|||||||
return popup.setContentScale(scale);
|
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
|
// Private functions
|
||||||
|
|
||||||
_getPopup(id) {
|
_getPopup(id) {
|
||||||
@ -167,8 +189,9 @@ class PopupFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_convertPopupPointToRootPagePoint(popup, x, y) {
|
_convertPopupPointToRootPagePoint(popup, x, y) {
|
||||||
if (popup.parent !== null) {
|
const parent = popup.parent;
|
||||||
const popupRect = popup.parent.getFrameRect();
|
if (parent !== null) {
|
||||||
|
const popupRect = parent.getFrameRect();
|
||||||
x += popupRect.x;
|
x += popupRect.x;
|
||||||
y += popupRect.y;
|
y += popupRect.y;
|
||||||
}
|
}
|
||||||
@ -176,6 +199,7 @@ class PopupFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_popupCanShow(popup) {
|
_popupCanShow(popup) {
|
||||||
return popup.parent === null || popup.parent.isVisibleSync();
|
const parent = popup.parent;
|
||||||
|
return parent === null || parent.isVisibleSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,30 @@ class PopupProxy extends EventDispatcher {
|
|||||||
return null;
|
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() {
|
get depth() {
|
||||||
return this._depth;
|
return this._depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get frameContentWindow() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
get container() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Public functions
|
// Public functions
|
||||||
|
|
||||||
async prepare() {
|
async prepare() {
|
||||||
@ -56,10 +76,6 @@ class PopupProxy extends EventDispatcher {
|
|||||||
this._id = id;
|
this._id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
isProxy() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
setOptionsContext(optionsContext, source) {
|
setOptionsContext(optionsContext, source) {
|
||||||
return this._invokeSafe('setOptionsContext', {id: this._id, 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});
|
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
|
// Private
|
||||||
|
|
||||||
_invoke(action, params={}) {
|
_invoke(action, params={}) {
|
||||||
|
@ -64,16 +64,28 @@ class Popup {
|
|||||||
return this._parent;
|
return this._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set parent(value) {
|
||||||
|
this._parent = value;
|
||||||
|
}
|
||||||
|
|
||||||
get child() {
|
get child() {
|
||||||
return this._child;
|
return this._child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set child(value) {
|
||||||
|
this._child = value;
|
||||||
|
}
|
||||||
|
|
||||||
get depth() {
|
get depth() {
|
||||||
return this._depth;
|
return this._depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
get frameId() {
|
get frameContentWindow() {
|
||||||
return this._frameId;
|
return this._frame.contentWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
get container() {
|
||||||
|
return this._container;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public functions
|
// Public functions
|
||||||
@ -86,10 +98,6 @@ class Popup {
|
|||||||
yomichan.on('extensionUnloaded', this._onExtensionUnloaded.bind(this));
|
yomichan.on('extensionUnloaded', this._onExtensionUnloaded.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
isProxy() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async setOptionsContext(optionsContext, source) {
|
async setOptionsContext(optionsContext, source) {
|
||||||
this._optionsContext = optionsContext;
|
this._optionsContext = optionsContext;
|
||||||
this._previousOptionsContextSource = source;
|
this._previousOptionsContextSource = source;
|
||||||
@ -163,26 +171,6 @@ class Popup {
|
|||||||
this._invokeSafe('setContentScale', {scale});
|
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() {
|
isVisibleSync() {
|
||||||
return (this._visibleOverride !== null ? this._visibleOverride : this._visible);
|
return (this._visibleOverride !== null ? this._visibleOverride : this._visible);
|
||||||
}
|
}
|
||||||
@ -205,18 +193,10 @@ class Popup {
|
|||||||
this._childrenSupported = value;
|
this._childrenSupported = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFrame() {
|
|
||||||
return this._frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
getFrameRect() {
|
getFrameRect() {
|
||||||
return this._frame.getBoundingClientRect();
|
return this._frame.getBoundingClientRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
getContainer() {
|
|
||||||
return this._container;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
|
|
||||||
_inject() {
|
_inject() {
|
||||||
@ -418,7 +398,7 @@ class Popup {
|
|||||||
_focusParent() {
|
_focusParent() {
|
||||||
if (this._parent !== null) {
|
if (this._parent !== null) {
|
||||||
// Chrome doesn't like focusing iframe without contentWindow.
|
// Chrome doesn't like focusing iframe without contentWindow.
|
||||||
const contentWindow = this._parent.getFrame().contentWindow;
|
const contentWindow = this._parent.frameContentWindow;
|
||||||
if (contentWindow !== null) {
|
if (contentWindow !== null) {
|
||||||
contentWindow.focus();
|
contentWindow.focus();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user