Display updates (#1057)
* Fix history assignment on the search page * Use clear instead of assigned * Simplify definitions assignment * Organize * Fix query not being cleared * Fix media loading * Fix potential issue with options not being assigned * Catch error when frameId is null, causing infinite loop * Fix frontend construction parameters
This commit is contained in:
parent
068b1eef71
commit
de299c64ae
@ -143,7 +143,7 @@ class DisplaySearch extends Display {
|
|||||||
await this.updateOptions();
|
await this.updateOptions();
|
||||||
const query = this._queryInput.value;
|
const query = this._queryInput.value;
|
||||||
if (query) {
|
if (query) {
|
||||||
this._search(false);
|
this._search(false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ class DisplaySearch extends Display {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'terms':
|
case 'terms':
|
||||||
case 'kanji':
|
case 'kanji':
|
||||||
animate = content.animate;
|
animate = !!content.animate;
|
||||||
valid = content.definitions.length > 0;
|
valid = content.definitions.length > 0;
|
||||||
this.blurElement(this._queryInput);
|
this.blurElement(this._queryInput);
|
||||||
break;
|
break;
|
||||||
@ -182,12 +182,12 @@ class DisplaySearch extends Display {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopImmediatePropagation();
|
e.stopImmediatePropagation();
|
||||||
this.blurElement(e.currentTarget);
|
this.blurElement(e.currentTarget);
|
||||||
this._search(true);
|
this._search(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSearch(e) {
|
_onSearch(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._search(true);
|
this._search(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCopy() {
|
_onCopy() {
|
||||||
@ -197,7 +197,7 @@ class DisplaySearch extends Display {
|
|||||||
|
|
||||||
_onExternalSearchUpdate({text, animate=true}) {
|
_onExternalSearchUpdate({text, animate=true}) {
|
||||||
this._queryInput.value = text;
|
this._queryInput.value = text;
|
||||||
this._search(animate);
|
this._search(animate, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onWanakanaEnableChange(e) {
|
_onWanakanaEnableChange(e) {
|
||||||
@ -342,11 +342,11 @@ class DisplaySearch extends Display {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_search(animate) {
|
_search(animate, history) {
|
||||||
const query = this._queryInput.value;
|
const query = this._queryInput.value;
|
||||||
const details = {
|
const details = {
|
||||||
focus: false,
|
focus: false,
|
||||||
history: false,
|
history,
|
||||||
params: {
|
params: {
|
||||||
query
|
query
|
||||||
},
|
},
|
||||||
|
@ -114,7 +114,7 @@ class PopupFactory {
|
|||||||
const popup = new Popup({
|
const popup = new Popup({
|
||||||
id,
|
id,
|
||||||
depth,
|
depth,
|
||||||
frameId,
|
frameId: this._frameId,
|
||||||
ownerFrameId,
|
ownerFrameId,
|
||||||
childrenSupported
|
childrenSupported
|
||||||
});
|
});
|
||||||
@ -129,6 +129,9 @@ class PopupFactory {
|
|||||||
popup.prepare();
|
popup.prepare();
|
||||||
return popup;
|
return popup;
|
||||||
} else {
|
} else {
|
||||||
|
if (frameId === null) {
|
||||||
|
throw new Error('Invalid frameId');
|
||||||
|
}
|
||||||
const useFrameOffsetForwarder = (parentPopupId === null);
|
const useFrameOffsetForwarder = (parentPopupId === null);
|
||||||
({id, depth, frameId} = await api.crossFrame.invoke(frameId, 'getOrCreatePopup', {
|
({id, depth, frameId} = await api.crossFrame.invoke(frameId, 'getOrCreatePopup', {
|
||||||
id,
|
id,
|
||||||
|
@ -522,6 +522,12 @@ class Display extends EventDispatcher {
|
|||||||
const token = {}; // Unique identifier token
|
const token = {}; // Unique identifier token
|
||||||
this._setContentToken = token;
|
this._setContentToken = token;
|
||||||
try {
|
try {
|
||||||
|
// Clear
|
||||||
|
this._closePopups();
|
||||||
|
this._eventListeners.removeAllEventListeners();
|
||||||
|
this._mediaLoader.unloadAll();
|
||||||
|
|
||||||
|
// Prepare
|
||||||
const urlSearchParams = new URLSearchParams(location.search);
|
const urlSearchParams = new URLSearchParams(location.search);
|
||||||
let type = urlSearchParams.get('type');
|
let type = urlSearchParams.get('type');
|
||||||
if (type === null) { type = 'terms'; }
|
if (type === null) { type = 'terms'; }
|
||||||
@ -530,36 +536,41 @@ class Display extends EventDispatcher {
|
|||||||
this._queryParserVisibleOverride = (fullVisible === null ? null : (fullVisible !== 'false'));
|
this._queryParserVisibleOverride = (fullVisible === null ? null : (fullVisible !== 'false'));
|
||||||
this._updateQueryParser();
|
this._updateQueryParser();
|
||||||
|
|
||||||
this._closePopups();
|
let clear = true;
|
||||||
this._eventListeners.removeAllEventListeners();
|
|
||||||
|
|
||||||
let assigned = false;
|
|
||||||
const eventArgs = {type, urlSearchParams, token};
|
|
||||||
this._historyHasChanged = true;
|
this._historyHasChanged = true;
|
||||||
this._contentType = type;
|
this._contentType = type;
|
||||||
this._mediaLoader.unloadAll();
|
const eventArgs = {type, urlSearchParams, token};
|
||||||
|
|
||||||
|
// Set content
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'terms':
|
case 'terms':
|
||||||
case 'kanji':
|
case 'kanji':
|
||||||
{
|
{
|
||||||
|
let query = urlSearchParams.get('query');
|
||||||
|
if (!query) { break; }
|
||||||
|
|
||||||
|
clear = false;
|
||||||
const isTerms = (type === 'terms');
|
const isTerms = (type === 'terms');
|
||||||
assigned = await this._setContentTermsOrKanji(token, isTerms, urlSearchParams, eventArgs);
|
query = this.postProcessQuery(query);
|
||||||
|
let queryFull = urlSearchParams.get('full');
|
||||||
|
queryFull = (queryFull !== null ? this.postProcessQuery(queryFull) : query);
|
||||||
|
const wildcardsEnabled = (urlSearchParams.get('wildcards') !== 'off');
|
||||||
|
await this._setContentTermsOrKanji(token, isTerms, query, queryFull, wildcardsEnabled, eventArgs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'unloaded':
|
case 'unloaded':
|
||||||
{
|
{
|
||||||
|
clear = false;
|
||||||
const {content} = this._history;
|
const {content} = this._history;
|
||||||
eventArgs.content = content;
|
eventArgs.content = content;
|
||||||
this.trigger('contentUpdating', eventArgs);
|
this.trigger('contentUpdating', eventArgs);
|
||||||
this._setContentExtensionUnloaded();
|
this._setContentExtensionUnloaded();
|
||||||
assigned = true;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stale = (this._setContentToken !== token);
|
// Clear
|
||||||
if (!stale) {
|
if (clear) {
|
||||||
if (!assigned) {
|
|
||||||
type = 'clear';
|
type = 'clear';
|
||||||
this._contentType = type;
|
this._contentType = type;
|
||||||
const {content} = this._history;
|
const {content} = this._history;
|
||||||
@ -568,8 +579,8 @@ class Display extends EventDispatcher {
|
|||||||
this.trigger('contentUpdating', eventArgs);
|
this.trigger('contentUpdating', eventArgs);
|
||||||
this._clearContent();
|
this._clearContent();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
const stale = (this._setContentToken !== token);
|
||||||
eventArgs.stale = stale;
|
eventArgs.stale = stale;
|
||||||
this.trigger('contentUpdated', eventArgs);
|
this.trigger('contentUpdated', eventArgs);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -788,10 +799,10 @@ class Display extends EventDispatcher {
|
|||||||
document.documentElement.dataset.yomichanTheme = themeName;
|
document.documentElement.dataset.yomichanTheme = themeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
async _findDefinitions(isTerms, source, urlSearchParams, optionsContext) {
|
async _findDefinitions(isTerms, source, wildcardsEnabled, optionsContext) {
|
||||||
if (isTerms) {
|
if (isTerms) {
|
||||||
const findDetails = {};
|
const findDetails = {};
|
||||||
if (urlSearchParams.get('wildcards') !== 'off') {
|
if (wildcardsEnabled) {
|
||||||
const match = /^([*\uff0a]*)([\w\W]*?)([*\uff0a]*)$/.exec(source);
|
const match = /^([*\uff0a]*)([\w\W]*?)([*\uff0a]*)$/.exec(source);
|
||||||
if (match !== null) {
|
if (match !== null) {
|
||||||
if (match[1]) {
|
if (match[1]) {
|
||||||
@ -811,13 +822,7 @@ class Display extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _setContentTermsOrKanji(token, isTerms, urlSearchParams, eventArgs) {
|
async _setContentTermsOrKanji(token, isTerms, query, queryFull, wildcardsEnabled, eventArgs) {
|
||||||
let source = urlSearchParams.get('query');
|
|
||||||
if (!source) {
|
|
||||||
this._setFullQuery('');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let {state, content} = this._history;
|
let {state, content} = this._history;
|
||||||
let changeHistory = false;
|
let changeHistory = false;
|
||||||
if (!isObject(content)) {
|
if (!isObject(content)) {
|
||||||
@ -839,28 +844,30 @@ class Display extends EventDispatcher {
|
|||||||
if (typeof url !== 'string') { url = window.location.href; }
|
if (typeof url !== 'string') { url = window.location.href; }
|
||||||
sentence = this._getValidSentenceData(sentence);
|
sentence = this._getValidSentenceData(sentence);
|
||||||
|
|
||||||
source = this.postProcessQuery(source);
|
this._setFullQuery(queryFull);
|
||||||
let full = urlSearchParams.get('full');
|
this._setTitleText(query);
|
||||||
full = (full === null ? source : this.postProcessQuery(full));
|
|
||||||
this._setFullQuery(full);
|
|
||||||
this._setTitleText(source);
|
|
||||||
|
|
||||||
let {definitions} = content;
|
let {definitions} = content;
|
||||||
if (!Array.isArray(definitions)) {
|
if (!Array.isArray(definitions)) {
|
||||||
definitions = await this._findDefinitions(isTerms, source, urlSearchParams, optionsContext);
|
definitions = await this._findDefinitions(isTerms, query, wildcardsEnabled, optionsContext);
|
||||||
if (this._setContentToken !== token) { return true; }
|
if (this._setContentToken !== token) { return; }
|
||||||
content.definitions = definitions;
|
content.definitions = definitions;
|
||||||
changeHistory = true;
|
changeHistory = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._setOptionsContextIfDifferent(optionsContext);
|
await this._setOptionsContextIfDifferent(optionsContext);
|
||||||
if (this._setContentToken !== token) { return true; }
|
if (this._setContentToken !== token) { return; }
|
||||||
|
|
||||||
|
if (this._options === null) {
|
||||||
|
await this.updateOptions();
|
||||||
|
if (this._setContentToken !== token) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
if (changeHistory) {
|
if (changeHistory) {
|
||||||
this._replaceHistoryStateNoNavigate(state, content);
|
this._replaceHistoryStateNoNavigate(state, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
eventArgs.source = source;
|
eventArgs.source = query;
|
||||||
eventArgs.content = content;
|
eventArgs.content = content;
|
||||||
this.trigger('contentUpdating', eventArgs);
|
this.trigger('contentUpdating', eventArgs);
|
||||||
|
|
||||||
@ -880,7 +887,7 @@ class Display extends EventDispatcher {
|
|||||||
for (let i = 0, ii = definitions.length; i < ii; ++i) {
|
for (let i = 0, ii = definitions.length; i < ii; ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
await promiseTimeout(1);
|
await promiseTimeout(1);
|
||||||
if (this._setContentToken !== token) { return true; }
|
if (this._setContentToken !== token) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
const definition = definitions[i];
|
const definition = definitions[i];
|
||||||
@ -912,8 +919,6 @@ class Display extends EventDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._updateAdderButtons(token, isTerms, definitions);
|
this._updateAdderButtons(token, isTerms, definitions);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setContentExtensionUnloaded() {
|
_setContentExtensionUnloaded() {
|
||||||
@ -930,11 +935,13 @@ class Display extends EventDispatcher {
|
|||||||
this._updateNavigation(false, false);
|
this._updateNavigation(false, false);
|
||||||
this._setNoContentVisible(false);
|
this._setNoContentVisible(false);
|
||||||
this._setTitleText('');
|
this._setTitleText('');
|
||||||
|
this._setFullQuery('');
|
||||||
}
|
}
|
||||||
|
|
||||||
_clearContent() {
|
_clearContent() {
|
||||||
this._container.textContent = '';
|
this._container.textContent = '';
|
||||||
this._setTitleText('');
|
this._setTitleText('');
|
||||||
|
this._setFullQuery('');
|
||||||
}
|
}
|
||||||
|
|
||||||
_setNoContentVisible(visible) {
|
_setNoContentVisible(visible) {
|
||||||
@ -1566,7 +1573,7 @@ class Display extends EventDispatcher {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (this._frontendSetupPromise === null) {
|
if (this._frontendSetupPromise === null) {
|
||||||
this._frontendSetupPromise = this._setupNestedFrontend(isSearchPage);
|
this._frontendSetupPromise = this._setupNestedFrontend();
|
||||||
}
|
}
|
||||||
await this._frontendSetupPromise;
|
await this._frontendSetupPromise;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -1580,12 +1587,12 @@ class Display extends EventDispatcher {
|
|||||||
this._frontend.setDisabledOverride(!isEnabled);
|
this._frontend.setDisabledOverride(!isEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _setupNestedFrontend(isSearchPage) {
|
async _setupNestedFrontend() {
|
||||||
const setupNestedPopupsOptions = (
|
const setupNestedPopupsOptions = {
|
||||||
(isSearchPage) ?
|
useProxyPopup: this._parentFrameId !== null,
|
||||||
{useProxyPopup: false} :
|
parentPopupId: this._parentPopupId,
|
||||||
{useProxyPopup: true, parentPopupId: this._parentPopupId, parentFrameId: this._parentFrameId}
|
parentFrameId: this._parentFrameId
|
||||||
);
|
};
|
||||||
|
|
||||||
const {frameId} = await api.frameInformationGet();
|
const {frameId} = await api.frameInformationGet();
|
||||||
|
|
||||||
|
@ -27,13 +27,13 @@ class MediaLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadMedia(path, dictionaryName, onLoad, onUnload) {
|
async loadMedia(path, dictionaryName, onLoad, onUnload) {
|
||||||
const token = this.token;
|
const token = this._token;
|
||||||
const data = {onUnload, loaded: false};
|
const data = {onUnload, loaded: false};
|
||||||
|
|
||||||
this._loadMediaData.push(data);
|
this._loadMediaData.push(data);
|
||||||
|
|
||||||
const media = await this.getMedia(path, dictionaryName);
|
const media = await this.getMedia(path, dictionaryName);
|
||||||
if (token !== this.token) { return; }
|
if (token !== this._token) { return; }
|
||||||
|
|
||||||
onLoad(media.url);
|
onLoad(media.url);
|
||||||
data.loaded = true;
|
data.loaded = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user