Update Popup and DisplayFloat optionsContext from Frontend (#464)
* set optionsContext from Frontend * update Popup+Display options on Frontend change * remove popup setOptions * only update DisplayFloat options from Frontend * fix optionsContext usage * fix preview frame arguments * keep Frontend URL up to date * cache url * fix preview frame * trigger modifyingProfileChange in correct places * remove async from function not using await * refactor optionsContext in Frontend
This commit is contained in:
parent
a49e4ccc4e
commit
ca033a87a0
@ -76,6 +76,8 @@ class DisplaySearch extends Display {
|
||||
async prepare() {
|
||||
try {
|
||||
await super.prepare();
|
||||
await this.updateOptions();
|
||||
yomichan.on('optionsUpdated', () => this.updateOptions());
|
||||
await this.queryParser.prepare();
|
||||
|
||||
const {queryParams: {query='', mode=''}} = parseUrl(window.location.href);
|
||||
@ -231,7 +233,7 @@ class DisplaySearch extends Display {
|
||||
this.setIntroVisible(!valid, animate);
|
||||
this.updateSearchButton();
|
||||
if (valid) {
|
||||
const {definitions} = await apiTermsFind(query, details, this.optionsContext);
|
||||
const {definitions} = await apiTermsFind(query, details, this.getOptionsContext());
|
||||
this.setContent('terms', {definitions, context: {
|
||||
focus: false,
|
||||
disableHistory: true,
|
||||
|
@ -19,7 +19,6 @@
|
||||
* SettingsPopupPreview
|
||||
*/
|
||||
|
||||
(async () => {
|
||||
const instance = new SettingsPopupPreview();
|
||||
await instance.prepare();
|
||||
(() => {
|
||||
new SettingsPopupPreview();
|
||||
})();
|
||||
|
@ -32,19 +32,24 @@ class SettingsPopupPreview {
|
||||
this.popupShown = false;
|
||||
this.themeChangeTimeout = null;
|
||||
this.textSource = null;
|
||||
this.optionsContext = null;
|
||||
this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, '');
|
||||
|
||||
this._windowMessageHandlers = new Map([
|
||||
['prepare', ({optionsContext}) => this.prepare(optionsContext)],
|
||||
['setText', ({text}) => this.setText(text)],
|
||||
['setCustomCss', ({css}) => this.setCustomCss(css)],
|
||||
['setCustomOuterCss', ({css}) => this.setCustomOuterCss(css)]
|
||||
['setCustomOuterCss', ({css}) => this.setCustomOuterCss(css)],
|
||||
['updateOptionsContext', ({optionsContext}) => this.updateOptionsContext(optionsContext)]
|
||||
]);
|
||||
|
||||
window.addEventListener('message', this.onMessage.bind(this), false);
|
||||
}
|
||||
|
||||
async prepare() {
|
||||
// Setup events
|
||||
window.addEventListener('message', this.onMessage.bind(this), false);
|
||||
async prepare(optionsContext) {
|
||||
this.optionsContext = optionsContext;
|
||||
|
||||
// Setup events
|
||||
document.querySelector('#theme-dark-checkbox').addEventListener('change', this.onThemeDarkCheckboxChanged.bind(this), false);
|
||||
|
||||
// Overwrite API functions
|
||||
@ -62,8 +67,9 @@ class SettingsPopupPreview {
|
||||
|
||||
this.frontend = new Frontend(this.popup);
|
||||
|
||||
this.frontend.getOptionsContext = async () => this.optionsContext;
|
||||
this.frontend.setEnabled = () => {};
|
||||
this.frontend.searchClear = () => {};
|
||||
this.frontend.onSearchClear = () => {};
|
||||
|
||||
await this.frontend.prepare();
|
||||
|
||||
@ -145,6 +151,12 @@ class SettingsPopupPreview {
|
||||
this.frontend.popup.setCustomOuterCss(css, false);
|
||||
}
|
||||
|
||||
async updateOptionsContext(optionsContext) {
|
||||
this.optionsContext = optionsContext;
|
||||
await this.frontend.updateOptions();
|
||||
await this.updateSearch();
|
||||
}
|
||||
|
||||
async updateSearch() {
|
||||
const exampleText = document.querySelector('#example-text');
|
||||
if (exampleText === null) { return; }
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
/* global
|
||||
* getOptionsContext
|
||||
* wanakana
|
||||
*/
|
||||
|
||||
@ -60,6 +61,23 @@ function showAppearancePreview() {
|
||||
frame.contentWindow.postMessage({action, params}, targetOrigin);
|
||||
});
|
||||
|
||||
const updateOptionsContext = () => {
|
||||
const action = 'updateOptionsContext';
|
||||
const params = {
|
||||
optionsContext: getOptionsContext()
|
||||
};
|
||||
frame.contentWindow.postMessage({action, params}, targetOrigin);
|
||||
};
|
||||
yomichan.on('modifyingProfileChange', updateOptionsContext);
|
||||
|
||||
frame.addEventListener('load', () => {
|
||||
const action = 'prepare';
|
||||
const params = {
|
||||
optionsContext: getOptionsContext()
|
||||
};
|
||||
frame.contentWindow.postMessage({action, params}, targetOrigin);
|
||||
});
|
||||
|
||||
container.append(frame);
|
||||
buttonContainer.remove();
|
||||
settings.css('display', '');
|
||||
|
@ -190,6 +190,8 @@ async function onTargetProfileChanged() {
|
||||
currentProfileIndex = index;
|
||||
|
||||
await profileOptionsUpdateTarget(optionsFull);
|
||||
|
||||
yomichan.trigger('modifyingProfileChange');
|
||||
}
|
||||
|
||||
async function onProfileAdd() {
|
||||
@ -197,9 +199,13 @@ async function onProfileAdd() {
|
||||
const profile = utilBackgroundIsolate(optionsFull.profiles[currentProfileIndex]);
|
||||
profile.name = profileOptionsCreateCopyName(profile.name, optionsFull.profiles, 100);
|
||||
optionsFull.profiles.push(profile);
|
||||
|
||||
currentProfileIndex = optionsFull.profiles.length - 1;
|
||||
|
||||
await profileOptionsUpdateTarget(optionsFull);
|
||||
await settingsSaveOptions();
|
||||
|
||||
yomichan.trigger('modifyingProfileChange');
|
||||
}
|
||||
|
||||
async function onProfileRemove(e) {
|
||||
@ -238,6 +244,8 @@ async function onProfileRemoveConfirm() {
|
||||
|
||||
await profileOptionsUpdateTarget(optionsFull);
|
||||
await settingsSaveOptions();
|
||||
|
||||
yomichan.trigger('modifyingProfileChange');
|
||||
}
|
||||
|
||||
function onProfileNameChanged() {
|
||||
@ -263,6 +271,8 @@ async function onProfileMove(offset) {
|
||||
|
||||
await profileOptionsUpdateTarget(optionsFull);
|
||||
await settingsSaveOptions();
|
||||
|
||||
yomichan.trigger('modifyingProfileChange');
|
||||
}
|
||||
|
||||
async function onProfileCopy() {
|
||||
|
@ -25,7 +25,7 @@
|
||||
* apiOptionsGet
|
||||
*/
|
||||
|
||||
async function createIframePopupProxy(url, frameOffsetForwarder, setDisabled) {
|
||||
async function createIframePopupProxy(frameOffsetForwarder, setDisabled) {
|
||||
const rootPopupInformationPromise = yomichan.getTemporaryListenerResult(
|
||||
chrome.runtime.onMessage,
|
||||
({action, params}, {resolve}) => {
|
||||
@ -39,7 +39,7 @@ async function createIframePopupProxy(url, frameOffsetForwarder, setDisabled) {
|
||||
|
||||
const getFrameOffset = frameOffsetForwarder.getOffset.bind(frameOffsetForwarder);
|
||||
|
||||
const popup = new PopupProxy(popupId, 0, null, frameId, url, getFrameOffset, setDisabled);
|
||||
const popup = new PopupProxy(popupId, 0, null, frameId, getFrameOffset, setDisabled);
|
||||
await popup.prepare();
|
||||
|
||||
return popup;
|
||||
@ -54,8 +54,8 @@ async function getOrCreatePopup(depth) {
|
||||
return popup;
|
||||
}
|
||||
|
||||
async function createPopupProxy(depth, id, parentFrameId, url) {
|
||||
const popup = new PopupProxy(null, depth + 1, id, parentFrameId, url);
|
||||
async function createPopupProxy(depth, id, parentFrameId) {
|
||||
const popup = new PopupProxy(null, depth + 1, id, parentFrameId);
|
||||
await popup.prepare();
|
||||
|
||||
return popup;
|
||||
@ -86,8 +86,22 @@ async function createPopupProxy(depth, id, parentFrameId, url) {
|
||||
applyOptions();
|
||||
};
|
||||
|
||||
let urlUpdatedAt = 0;
|
||||
let proxyHostUrlCached = url;
|
||||
const getProxyHostUrl = async () => {
|
||||
const now = Date.now();
|
||||
if (popups.proxy !== null && now - urlUpdatedAt > 500) {
|
||||
proxyHostUrlCached = await popups.proxy.getHostUrl();
|
||||
urlUpdatedAt = now;
|
||||
}
|
||||
return proxyHostUrlCached;
|
||||
};
|
||||
|
||||
const applyOptions = async () => {
|
||||
const optionsContext = {depth: isSearchPage ? 0 : depth, url};
|
||||
const optionsContext = {
|
||||
depth: isSearchPage ? 0 : depth,
|
||||
url: proxy ? await getProxyHostUrl() : window.location.href
|
||||
};
|
||||
const options = await apiOptionsGet(optionsContext);
|
||||
|
||||
if (!proxy && frameOffsetForwarder === null) {
|
||||
@ -97,10 +111,10 @@ async function createPopupProxy(depth, id, parentFrameId, url) {
|
||||
|
||||
let popup;
|
||||
if (isIframe && options.general.showIframePopupsInRootFrame && DOM.getFullscreenElement() === null && iframePopupsInRootFrameAvailable) {
|
||||
popup = popups.iframe || await createIframePopupProxy(url, frameOffsetForwarder, disableIframePopupsInRootFrame);
|
||||
popup = popups.iframe || await createIframePopupProxy(frameOffsetForwarder, disableIframePopupsInRootFrame);
|
||||
popups.iframe = popup;
|
||||
} else if (proxy) {
|
||||
popup = popups.proxy || await createPopupProxy(depth, id, parentFrameId, url);
|
||||
popup = popups.proxy || await createPopupProxy(depth, id, parentFrameId);
|
||||
popups.proxy = popup;
|
||||
} else {
|
||||
popup = popups.normal || await getOrCreatePopup(depth);
|
||||
@ -108,7 +122,8 @@ async function createPopupProxy(depth, id, parentFrameId, url) {
|
||||
}
|
||||
|
||||
if (frontend === null) {
|
||||
frontend = new Frontend(popup);
|
||||
const getUrl = proxy ? getProxyHostUrl : null;
|
||||
frontend = new Frontend(popup, getUrl);
|
||||
frontendPreparePromise = frontend.prepare();
|
||||
await frontendPreparePromise;
|
||||
} else {
|
||||
|
@ -29,11 +29,6 @@ class DisplayFloat extends Display {
|
||||
|
||||
this._popupId = null;
|
||||
|
||||
this.optionsContext = {
|
||||
depth: 0,
|
||||
url: window.location.href
|
||||
};
|
||||
|
||||
this._orphaned = false;
|
||||
this._prepareInvoked = false;
|
||||
this._messageToken = null;
|
||||
@ -51,10 +46,11 @@ class DisplayFloat extends Display {
|
||||
]);
|
||||
|
||||
this._windowMessageHandlers = new Map([
|
||||
['setOptionsContext', ({optionsContext}) => this.setOptionsContext(optionsContext)],
|
||||
['setContent', ({type, details}) => this.setContent(type, details)],
|
||||
['clearAutoPlayTimer', () => this.clearAutoPlayTimer()],
|
||||
['setCustomCss', ({css}) => this.setCustomCss(css)],
|
||||
['prepare', ({popupInfo, url, childrenSupported, scale}) => this.prepare(popupInfo, url, childrenSupported, scale)],
|
||||
['prepare', ({popupInfo, optionsContext, childrenSupported, scale}) => this.prepare(popupInfo, optionsContext, childrenSupported, scale)],
|
||||
['setContentScale', ({scale}) => this.setContentScale(scale)]
|
||||
]);
|
||||
|
||||
@ -62,18 +58,20 @@ class DisplayFloat extends Display {
|
||||
window.addEventListener('message', this.onMessage.bind(this), false);
|
||||
}
|
||||
|
||||
async prepare(popupInfo, url, childrenSupported, scale) {
|
||||
async prepare(popupInfo, optionsContext, childrenSupported, scale) {
|
||||
if (this._prepareInvoked) { return; }
|
||||
this._prepareInvoked = true;
|
||||
|
||||
const {id, depth, parentFrameId} = popupInfo;
|
||||
const {id, parentFrameId} = popupInfo;
|
||||
this._popupId = id;
|
||||
this.optionsContext.depth = depth;
|
||||
this.optionsContext.url = url;
|
||||
|
||||
this.optionsContext = optionsContext;
|
||||
|
||||
await super.prepare();
|
||||
await this.updateOptions();
|
||||
|
||||
if (childrenSupported) {
|
||||
const {depth, url} = optionsContext;
|
||||
popupNestedInitialize(id, depth, parentFrameId, url);
|
||||
}
|
||||
|
||||
@ -158,6 +156,11 @@ class DisplayFloat extends Display {
|
||||
}
|
||||
}
|
||||
|
||||
async setOptionsContext(optionsContext) {
|
||||
this.optionsContext = optionsContext;
|
||||
await this.updateOptions();
|
||||
}
|
||||
|
||||
setContentScale(scale) {
|
||||
document.body.style.fontSize = `${scale}em`;
|
||||
}
|
||||
|
@ -26,24 +26,23 @@
|
||||
*/
|
||||
|
||||
class Frontend extends TextScanner {
|
||||
constructor(popup) {
|
||||
constructor(popup, getUrl=null) {
|
||||
super(
|
||||
window,
|
||||
() => this.popup.isProxy() ? [] : [this.popup.getContainer()],
|
||||
[(x, y) => this.popup.containsPoint(x, y)]
|
||||
);
|
||||
|
||||
this._id = yomichan.generateId(16);
|
||||
|
||||
this.popup = popup;
|
||||
|
||||
this._getUrl = getUrl;
|
||||
|
||||
this._disabledOverride = false;
|
||||
|
||||
this.options = null;
|
||||
|
||||
this.optionsContext = {
|
||||
depth: popup.depth,
|
||||
url: popup.url
|
||||
};
|
||||
|
||||
this._pageZoomFactor = 1.0;
|
||||
this._contentScale = 1.0;
|
||||
this._orphaned = false;
|
||||
@ -143,11 +142,12 @@ class Frontend extends TextScanner {
|
||||
async setPopup(popup) {
|
||||
this.onSearchClear(false);
|
||||
this.popup = popup;
|
||||
await popup.setOptions(this.options);
|
||||
await popup.setOptionsContext(await this.getOptionsContext(), this._id);
|
||||
}
|
||||
|
||||
async updateOptions() {
|
||||
this.options = await apiOptionsGet(this.getOptionsContext());
|
||||
const optionsContext = await this.getOptionsContext();
|
||||
this.options = await apiOptionsGet(optionsContext);
|
||||
this.setOptions(this.options, this._canEnable());
|
||||
|
||||
const ignoreNodes = ['.scan-disable', '.scan-disable *'];
|
||||
@ -156,7 +156,7 @@ class Frontend extends TextScanner {
|
||||
}
|
||||
this.ignoreNodes = ignoreNodes.join(',');
|
||||
|
||||
await this.popup.setOptions(this.options);
|
||||
await this.popup.setOptionsContext(optionsContext, this._id);
|
||||
|
||||
this._updateContentScale();
|
||||
|
||||
@ -170,19 +170,20 @@ class Frontend extends TextScanner {
|
||||
|
||||
try {
|
||||
if (textSource !== null) {
|
||||
const optionsContext = await this.getOptionsContext();
|
||||
results = (
|
||||
await this.findTerms(textSource) ||
|
||||
await this.findKanji(textSource)
|
||||
await this.findTerms(textSource, optionsContext) ||
|
||||
await this.findKanji(textSource, optionsContext)
|
||||
);
|
||||
if (results !== null) {
|
||||
const focus = (cause === 'mouse');
|
||||
this.showContent(textSource, focus, results.definitions, results.type);
|
||||
this.showContent(textSource, focus, results.definitions, results.type, optionsContext);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (this._orphaned) {
|
||||
if (textSource !== null && this.options.scanning.modifier !== 'none') {
|
||||
this._showPopupContent(textSource, 'orphaned');
|
||||
this._showPopupContent(textSource, await this.getOptionsContext(), 'orphaned');
|
||||
}
|
||||
} else {
|
||||
this.onError(e);
|
||||
@ -196,11 +197,12 @@ class Frontend extends TextScanner {
|
||||
return results;
|
||||
}
|
||||
|
||||
showContent(textSource, focus, definitions, type) {
|
||||
showContent(textSource, focus, definitions, type, optionsContext) {
|
||||
const {url} = optionsContext;
|
||||
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
|
||||
const url = window.location.href;
|
||||
this._showPopupContent(
|
||||
textSource,
|
||||
optionsContext,
|
||||
type,
|
||||
{definitions, context: {sentence, url, focus, disableHistory: true}}
|
||||
);
|
||||
@ -210,13 +212,13 @@ class Frontend extends TextScanner {
|
||||
return this._lastShowPromise;
|
||||
}
|
||||
|
||||
async findTerms(textSource) {
|
||||
async findTerms(textSource, optionsContext) {
|
||||
this.setTextSourceScanLength(textSource, this.options.scanning.length);
|
||||
|
||||
const searchText = textSource.text();
|
||||
if (searchText.length === 0) { return null; }
|
||||
|
||||
const {definitions, length} = await apiTermsFind(searchText, {}, this.getOptionsContext());
|
||||
const {definitions, length} = await apiTermsFind(searchText, {}, optionsContext);
|
||||
if (definitions.length === 0) { return null; }
|
||||
|
||||
textSource.setEndOffset(length);
|
||||
@ -224,13 +226,13 @@ class Frontend extends TextScanner {
|
||||
return {definitions, type: 'terms'};
|
||||
}
|
||||
|
||||
async findKanji(textSource) {
|
||||
async findKanji(textSource, optionsContext) {
|
||||
this.setTextSourceScanLength(textSource, 1);
|
||||
|
||||
const searchText = textSource.text();
|
||||
if (searchText.length === 0) { return null; }
|
||||
|
||||
const definitions = await apiKanjiFind(searchText, this.getOptionsContext());
|
||||
const definitions = await apiKanjiFind(searchText, optionsContext);
|
||||
if (definitions.length === 0) { return null; }
|
||||
|
||||
return {definitions, type: 'kanji'};
|
||||
@ -242,17 +244,20 @@ class Frontend extends TextScanner {
|
||||
super.onSearchClear(changeFocus);
|
||||
}
|
||||
|
||||
getOptionsContext() {
|
||||
this.optionsContext.url = this.popup.url;
|
||||
return this.optionsContext;
|
||||
async getOptionsContext() {
|
||||
const url = this._getUrl !== null ? await this._getUrl() : window.location.href;
|
||||
const depth = this.popup.depth;
|
||||
return {depth, url};
|
||||
}
|
||||
|
||||
_showPopupContent(textSource, type=null, details=null) {
|
||||
_showPopupContent(textSource, optionsContext, type=null, details=null) {
|
||||
const context = {optionsContext, source: this._id};
|
||||
this._lastShowPromise = this.popup.showContent(
|
||||
textSource.getRect(),
|
||||
textSource.getWritingMode(),
|
||||
type,
|
||||
details
|
||||
details,
|
||||
context
|
||||
);
|
||||
return this._lastShowPromise;
|
||||
}
|
||||
@ -294,7 +299,7 @@ class Frontend extends TextScanner {
|
||||
async _updatePopupPosition() {
|
||||
const textSource = this.getCurrentTextSource();
|
||||
if (textSource !== null && await this.popup.isVisible()) {
|
||||
this._showPopupContent(textSource);
|
||||
this._showPopupContent(textSource, await this.getOptionsContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ class PopupProxyHost {
|
||||
|
||||
this._apiReceiver = new FrontendApiReceiver(`popup-proxy-host#${this._frameId}`, new Map([
|
||||
['getOrCreatePopup', this._onApiGetOrCreatePopup.bind(this)],
|
||||
['setOptions', this._onApiSetOptions.bind(this)],
|
||||
['setOptionsContext', this._onApiSetOptionsContext.bind(this)],
|
||||
['hide', this._onApiHide.bind(this)],
|
||||
['isVisible', this._onApiIsVisibleAsync.bind(this)],
|
||||
['setVisibleOverride', this._onApiSetVisibleOverride.bind(this)],
|
||||
@ -45,7 +45,8 @@ class PopupProxyHost {
|
||||
['showContent', this._onApiShowContent.bind(this)],
|
||||
['setCustomCss', this._onApiSetCustomCss.bind(this)],
|
||||
['clearAutoPlayTimer', this._onApiClearAutoPlayTimer.bind(this)],
|
||||
['setContentScale', this._onApiSetContentScale.bind(this)]
|
||||
['setContentScale', this._onApiSetContentScale.bind(this)],
|
||||
['getHostUrl', this._onApiGetHostUrl.bind(this)]
|
||||
]));
|
||||
}
|
||||
|
||||
@ -103,9 +104,9 @@ class PopupProxyHost {
|
||||
};
|
||||
}
|
||||
|
||||
async _onApiSetOptions({id, options}) {
|
||||
async _onApiSetOptionsContext({id, optionsContext, source}) {
|
||||
const popup = this._getPopup(id);
|
||||
return await popup.setOptions(options);
|
||||
return await popup.setOptionsContext(optionsContext, source);
|
||||
}
|
||||
|
||||
async _onApiHide({id, changeFocus}) {
|
||||
@ -129,11 +130,11 @@ class PopupProxyHost {
|
||||
return await popup.containsPoint(x, y);
|
||||
}
|
||||
|
||||
async _onApiShowContent({id, elementRect, writingMode, type, details}) {
|
||||
async _onApiShowContent({id, elementRect, writingMode, type, details, context}) {
|
||||
const popup = this._getPopup(id);
|
||||
elementRect = PopupProxyHost._convertJsonRectToDOMRect(popup, elementRect);
|
||||
if (!PopupProxyHost._popupCanShow(popup)) { return; }
|
||||
return await popup.showContent(elementRect, writingMode, type, details);
|
||||
return await popup.showContent(elementRect, writingMode, type, details, context);
|
||||
}
|
||||
|
||||
async _onApiSetCustomCss({id, css}) {
|
||||
@ -151,6 +152,10 @@ class PopupProxyHost {
|
||||
return popup.setContentScale(scale);
|
||||
}
|
||||
|
||||
async _onApiGetHostUrl() {
|
||||
return window.location.href;
|
||||
}
|
||||
|
||||
// Private functions
|
||||
|
||||
_getPopup(id) {
|
||||
|
@ -20,12 +20,11 @@
|
||||
*/
|
||||
|
||||
class PopupProxy {
|
||||
constructor(id, depth, parentId, parentFrameId, url, getFrameOffset=null, setDisabled=null) {
|
||||
constructor(id, depth, parentId, parentFrameId, getFrameOffset=null, setDisabled=null) {
|
||||
this._parentId = parentId;
|
||||
this._parentFrameId = parentFrameId;
|
||||
this._id = id;
|
||||
this._depth = depth;
|
||||
this._url = url;
|
||||
this._apiSender = new FrontendApiSender();
|
||||
this._getFrameOffset = getFrameOffset;
|
||||
this._setDisabled = setDisabled;
|
||||
@ -49,10 +48,6 @@ class PopupProxy {
|
||||
return this._depth;
|
||||
}
|
||||
|
||||
get url() {
|
||||
return this._url;
|
||||
}
|
||||
|
||||
// Public functions
|
||||
|
||||
async prepare() {
|
||||
@ -64,8 +59,8 @@ class PopupProxy {
|
||||
return true;
|
||||
}
|
||||
|
||||
async setOptions(options) {
|
||||
return await this._invokeHostApi('setOptions', {id: this._id, options});
|
||||
async setOptionsContext(optionsContext, source) {
|
||||
return await this._invokeHostApi('setOptionsContext', {id: this._id, optionsContext, source});
|
||||
}
|
||||
|
||||
hide(changeFocus) {
|
||||
@ -88,14 +83,14 @@ class PopupProxy {
|
||||
return await this._invokeHostApi('containsPoint', {id: this._id, x, y});
|
||||
}
|
||||
|
||||
async showContent(elementRect, writingMode, type=null, details=null) {
|
||||
async showContent(elementRect, writingMode, type, details, context) {
|
||||
let {x, y, width, height} = elementRect;
|
||||
if (this._getFrameOffset !== null) {
|
||||
await this._updateFrameOffset();
|
||||
[x, y] = this._applyFrameOffset(x, y);
|
||||
}
|
||||
elementRect = {x, y, width, height};
|
||||
return await this._invokeHostApi('showContent', {id: this._id, elementRect, writingMode, type, details});
|
||||
return await this._invokeHostApi('showContent', {id: this._id, elementRect, writingMode, type, details, context});
|
||||
}
|
||||
|
||||
async setCustomCss(css) {
|
||||
@ -110,6 +105,10 @@ class PopupProxy {
|
||||
this._invokeHostApi('setContentScale', {id: this._id, scale});
|
||||
}
|
||||
|
||||
async getHostUrl() {
|
||||
return await this._invokeHostApi('getHostUrl', {});
|
||||
}
|
||||
|
||||
// Private
|
||||
|
||||
_invokeHostApi(action, params={}) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
* DOM
|
||||
* apiGetMessageToken
|
||||
* apiInjectStylesheet
|
||||
* apiOptionsGet
|
||||
*/
|
||||
|
||||
class Popup {
|
||||
@ -33,10 +34,12 @@ class Popup {
|
||||
this._visible = false;
|
||||
this._visibleOverride = null;
|
||||
this._options = null;
|
||||
this._optionsContext = null;
|
||||
this._contentScale = 1.0;
|
||||
this._containerSizeContentScale = null;
|
||||
this._targetOrigin = chrome.runtime.getURL('/').replace(/\/$/, '');
|
||||
this._messageToken = null;
|
||||
this._previousOptionsContextSource = null;
|
||||
|
||||
this._container = document.createElement('iframe');
|
||||
this._container.className = 'yomichan-float';
|
||||
@ -72,19 +75,20 @@ class Popup {
|
||||
return this._frameId;
|
||||
}
|
||||
|
||||
get url() {
|
||||
return window.location.href;
|
||||
}
|
||||
|
||||
// Public functions
|
||||
|
||||
isProxy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
async setOptions(options) {
|
||||
this._options = options;
|
||||
async setOptionsContext(optionsContext, source) {
|
||||
this._optionsContext = optionsContext;
|
||||
this._previousOptionsContextSource = source;
|
||||
|
||||
this._options = await apiOptionsGet(optionsContext);
|
||||
this.updateTheme();
|
||||
|
||||
this._invokeApi('setOptionsContext', {optionsContext});
|
||||
}
|
||||
|
||||
hide(changeFocus) {
|
||||
@ -120,8 +124,14 @@ class Popup {
|
||||
return false;
|
||||
}
|
||||
|
||||
async showContent(elementRect, writingMode, type=null, details=null) {
|
||||
async showContent(elementRect, writingMode, type, details, context) {
|
||||
if (this._options === null) { throw new Error('Options not assigned'); }
|
||||
|
||||
const {optionsContext, source} = context;
|
||||
if (source !== this._previousOptionsContextSource) {
|
||||
await this.setOptionsContext(optionsContext, source);
|
||||
}
|
||||
|
||||
await this._show(elementRect, writingMode);
|
||||
if (type === null) { return; }
|
||||
this._invokeApi('setContent', {type, details});
|
||||
@ -219,10 +229,9 @@ class Popup {
|
||||
this._invokeApi('prepare', {
|
||||
popupInfo: {
|
||||
id: this._id,
|
||||
depth: this._depth,
|
||||
parentFrameId
|
||||
},
|
||||
url: this.url,
|
||||
optionsContext: this._optionsContext,
|
||||
childrenSupported: this._childrenSupported,
|
||||
scale: this._contentScale
|
||||
});
|
||||
|
@ -177,8 +177,6 @@ class Display {
|
||||
async prepare() {
|
||||
await yomichan.prepare();
|
||||
await this.displayGenerator.prepare();
|
||||
await this.updateOptions();
|
||||
yomichan.on('optionsUpdated', () => this.updateOptions());
|
||||
}
|
||||
|
||||
onError(_error) {
|
||||
|
Loading…
Reference in New Issue
Block a user