Refactor nested popup/frontend setup (#1052)

This commit is contained in:
toasted-nutbread 2020-11-22 11:19:21 -05:00 committed by GitHub
parent 7b6a4c4e36
commit 7234cce4ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 139 deletions

View File

@ -25,7 +25,7 @@
class DisplaySearch extends Display {
constructor() {
super();
super('search');
this._searchButton = document.querySelector('#search-button');
this._queryInput = document.querySelector('#search-textbox');
this._introElement = document.querySelector('#intro');
@ -85,8 +85,6 @@ class DisplaySearch extends Display {
this._onModeChange();
await this._prepareNestedPopups();
this.initializeState();
this._isPrepared = true;
@ -319,33 +317,6 @@ class DisplaySearch extends Display {
this._introElement.style.height = '0';
}
async _prepareNestedPopups() {
let complete = false;
const onOptionsUpdated = async () => {
const optionsContext = this.getOptionsContext();
const options = await api.optionsGet(optionsContext);
if (!options.scanning.enableOnSearchPage || complete) { return; }
complete = true;
yomichan.off('optionsUpdated', onOptionsUpdated);
try {
await this.setupNestedPopups({
depth: 1,
useProxyPopup: false,
pageType: 'search'
});
} catch (e) {
yomichan.logError(e);
}
};
yomichan.on('optionsUpdated', onOptionsUpdated);
await onOptionsUpdated();
}
async _setClipboardMonitorEnabled(value) {
let modify = true;
if (value) {

View File

@ -23,8 +23,7 @@
class DisplayFloat extends Display {
constructor() {
super();
this._nestedPopupsPrepared = false;
super('popup');
this._frameEndpoint = new FrameEndpoint();
this._windowMessageHandlers = new Map([
['extensionUnloaded', {async: false, handler: this._onMessageExtensionUnloaded.bind(this)}]
@ -48,10 +47,6 @@ class DisplayFloat extends Display {
const {browser} = await api.getEnvironmentInfo();
this._browser = browser;
this.registerDirectMessageHandlers([
['configure', {async: true, handler: this._onMessageConfigure.bind(this)}],
['setContentScale', {async: false, handler: this._onMessageSetContentScale.bind(this)}]
]);
window.addEventListener('message', this._onWindowMessage.bind(this), false);
document.documentElement.addEventListener('mouseup', this._onMouseUp.bind(this), false);
document.documentElement.addEventListener('click', this._onClick.bind(this), false);
@ -101,23 +96,6 @@ class DisplayFloat extends Display {
yomichan.invokeMessageHandler(messageHandler, params, callback);
}
async _onMessageConfigure({frameId, ownerFrameId, popupId, optionsContext, childrenSupported, scale}) {
this.ownerFrameId = ownerFrameId;
await this.setOptionsContext(optionsContext);
if (childrenSupported && !this._nestedPopupsPrepared) {
const {depth} = optionsContext;
this._prepareNestedPopups(depth + 1, popupId, frameId);
this._nestedPopupsPrepared = true;
}
this._setContentScale(scale);
}
_onMessageSetContentScale({scale}) {
this._setContentScale(scale);
}
_onMessageExtensionUnloaded() {
if (yomichan.isExtensionUnloaded) { return; }
yomichan.triggerExtensionUnloaded();
@ -200,42 +178,6 @@ class DisplayFloat extends Display {
parent.removeChild(textarea);
}
_setContentScale(scale) {
const body = document.body;
if (body === null) { return; }
body.style.fontSize = `${scale}em`;
}
async _prepareNestedPopups(depth, parentPopupId, parentFrameId) {
let complete = false;
const onOptionsUpdated = async () => {
const optionsContext = this.getOptionsContext();
const options = await api.optionsGet(optionsContext);
const maxPopupDepthExceeded = !(typeof depth === 'number' && depth <= options.scanning.popupNestingMaxDepth);
if (maxPopupDepthExceeded || complete) { return; }
complete = true;
yomichan.off('optionsUpdated', onOptionsUpdated);
try {
await this.setupNestedPopups({
depth,
parentPopupId,
parentFrameId,
useProxyPopup: true,
pageType: 'popup'
});
} catch (e) {
yomichan.logError(e);
}
};
yomichan.on('optionsUpdated', onOptionsUpdated);
await onOptionsUpdated();
}
_invokeOwner(action, params={}) {
return api.crossFrame.invoke(this.ownerFrameId, action, params);
}

View File

@ -379,10 +379,6 @@ class Frontend {
}
if (this._updatePopupToken !== token) { return; }
if (this._pageType === 'search') {
this.setDisabledOverride(!this._options.scanning.enableOnSearchPage);
}
this._clearSelection(true);
this._popupEventListeners.removeAllEventListeners();
this._popup = popup;
@ -525,11 +521,7 @@ class Frontend {
}
_updateTextScannerEnabled() {
const enabled = (
this._options.general.enable &&
this._depth <= this._options.scanning.popupNestingMaxDepth &&
!this._disabledOverride
);
const enabled = (this._options.general.enable && !this._disabledOverride);
this._textScanner.setEnabled(enabled);
}

View File

@ -255,12 +255,13 @@ class Popup extends EventDispatcher {
// Configure
await this._invokeSafe('configure', {
frameId: this._frameId,
depth: this._depth,
parentPopupId: this._id,
parentFrameId: this._frameId,
ownerFrameId: this._ownerFrameId,
popupId: this._id,
optionsContext: this._optionsContext,
childrenSupported: this._childrenSupported,
scale: this._contentScale
scale: this._contentScale,
optionsContext: this._optionsContext
});
}

View File

@ -32,8 +32,9 @@
*/
class Display extends EventDispatcher {
constructor() {
constructor(pageType) {
super();
this._pageType = pageType;
this._container = document.querySelector('#definitions');
this._definitions = [];
this._optionsContext = {depth: 0, url: window.location.href};
@ -79,7 +80,6 @@ class Display extends EventDispatcher {
documentUtil: this._documentUtil
});
this._mode = null;
this._ownerFrameId = null;
this._defaultAnkiFieldTemplates = null;
this._defaultAnkiFieldTemplatesPromise = null;
this._templateRenderer = new TemplateRendererProxy();
@ -95,6 +95,13 @@ class Display extends EventDispatcher {
this._closeButton = document.querySelector('#close-button');
this._navigationPreviousButton = document.querySelector('#navigate-previous-button');
this._navigationNextButton = document.querySelector('#navigate-next-button');
this._frontend = null;
this._frontendSetupPromise = null;
this._depth = 0;
this._parentPopupId = null;
this._parentFrameId = null;
this._ownerFrameId = null;
this._childrenSupported = true;
this.registerActions([
['close', () => { this.onEscape(); }],
@ -135,7 +142,9 @@ class Display extends EventDispatcher {
['setOptionsContext', {async: false, handler: this._onMessageSetOptionsContext.bind(this)}],
['setContent', {async: false, handler: this._onMessageSetContent.bind(this)}],
['clearAutoPlayTimer', {async: false, handler: this._onMessageClearAutoPlayTimer.bind(this)}],
['setCustomCss', {async: false, handler: this._onMessageSetCustomCss.bind(this)}]
['setCustomCss', {async: false, handler: this._onMessageSetCustomCss.bind(this)}],
['setContentScale', {async: false, handler: this._onMessageSetContentScale.bind(this)}],
['configure', {async: true, handler: this._onMessageConfigure.bind(this)}]
]);
}
@ -164,10 +173,6 @@ class Display extends EventDispatcher {
return this._ownerFrameId;
}
set ownerFrameId(value) {
this._ownerFrameId = value;
}
async prepare() {
this._audioSystem.prepare();
this._updateMode();
@ -268,6 +273,8 @@ class Display extends EventDispatcher {
preventMiddleMouse: scanning.preventMiddleMouse.onSearchQuery
}
});
this._updateNestedFrontend(options);
}
addMultipleEventListeners(selector, type, listener, options) {
@ -365,36 +372,6 @@ class Display extends EventDispatcher {
}
}
async setupNestedPopups({depth, parentPopupId, parentFrameId, useProxyPopup, pageType}) {
await dynamicLoader.loadScripts([
'/mixed/js/text-scanner.js',
'/mixed/js/frame-client.js',
'/fg/js/popup.js',
'/fg/js/popup-proxy.js',
'/fg/js/popup-window.js',
'/fg/js/popup-factory.js',
'/fg/js/frame-offset-forwarder.js',
'/fg/js/frontend.js'
]);
const {frameId} = await api.frameInformationGet();
const popupFactory = new PopupFactory(frameId);
popupFactory.prepare();
const frontend = new Frontend({
frameId,
popupFactory,
depth,
parentPopupId,
parentFrameId,
useProxyPopup,
pageType,
allowRootFramePopupProxy: true
});
await frontend.prepare();
}
authenticateMessageData(data) {
return data;
}
@ -453,6 +430,20 @@ class Display extends EventDispatcher {
this.setCustomCss(css);
}
_onMessageSetContentScale({scale}) {
this._setContentScale(scale);
}
async _onMessageConfigure({depth, parentPopupId, parentFrameId, ownerFrameId, childrenSupported, scale, optionsContext}) {
this._depth = depth;
this._parentPopupId = parentPopupId;
this._parentFrameId = parentFrameId;
this._ownerFrameId = ownerFrameId;
this._childrenSupported = childrenSupported;
this._setContentScale(scale);
await this.setOptionsContext(optionsContext);
}
// Private
async _onStateChanged() {
@ -1568,4 +1559,73 @@ class Display extends EventDispatcher {
target.focus({preventScroll: true});
}
}
_setContentScale(scale) {
const body = document.body;
if (body === null) { return; }
body.style.fontSize = `${scale}em`;
}
async _updateNestedFrontend(options) {
const isSearchPage = (this._pageType === 'search');
const isEnabled = this._childrenSupported && (
(isSearchPage) ?
(options.scanning.enableOnSearchPage) :
(this._depth < options.scanning.popupNestingMaxDepth)
);
if (this._frontend === null) {
if (!isEnabled) { return; }
try {
if (this._frontendSetupPromise === null) {
this._frontendSetupPromise = this._setupNestedFrontend(isSearchPage);
}
await this._frontendSetupPromise;
} catch (e) {
yomichan.logError(e);
return;
} finally {
this._frontendSetupPromise = null;
}
}
this._frontend.setDisabledOverride(!isEnabled);
}
async _setupNestedFrontend(isSearchPage) {
const setupNestedPopupsOptions = (
(isSearchPage) ?
{useProxyPopup: false} :
{useProxyPopup: true, parentPopupId: this._parentPopupId, parentFrameId: this._parentFrameId}
);
const {frameId} = await api.frameInformationGet();
await dynamicLoader.loadScripts([
'/mixed/js/text-scanner.js',
'/mixed/js/frame-client.js',
'/fg/js/popup.js',
'/fg/js/popup-proxy.js',
'/fg/js/popup-window.js',
'/fg/js/popup-factory.js',
'/fg/js/frame-offset-forwarder.js',
'/fg/js/frontend.js'
]);
const popupFactory = new PopupFactory(frameId);
popupFactory.prepare();
Object.assign(setupNestedPopupsOptions, {
depth: this._depth + 1,
frameId,
popupFactory,
pageType: this._pageType,
allowRootFramePopupProxy: true
});
const frontend = new Frontend(setupNestedPopupsOptions);
this._frontend = frontend;
await frontend.prepare();
}
}