Refactor nested popup/frontend setup (#1052)
This commit is contained in:
parent
7b6a4c4e36
commit
7234cce4ae
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user