Search and display style updates (#1005)
* Use same selectors * Use consistent stylesheet declaration * Fix query parser not being cleared * Set property upon load * Don't focus for Enter key press * Update search page styles * Update indent and nodes * Support dark style * Add missing var
This commit is contained in:
parent
db9ec4c449
commit
8cf10d685d
@ -28,6 +28,7 @@
|
|||||||
const displaySearch = new DisplaySearch();
|
const displaySearch = new DisplaySearch();
|
||||||
await displaySearch.prepare();
|
await displaySearch.prepare();
|
||||||
|
|
||||||
|
document.documentElement.dataset.loaded = 'true';
|
||||||
yomichan.ready();
|
yomichan.ready();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
yomichan.logError(e);
|
yomichan.logError(e);
|
||||||
|
@ -25,12 +25,14 @@
|
|||||||
|
|
||||||
class DisplaySearch extends Display {
|
class DisplaySearch extends Display {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(document.querySelector('#spinner'), document.querySelector('#content'));
|
super();
|
||||||
this._searchButton = document.querySelector('#search');
|
this._searchButton = document.querySelector('#search-button');
|
||||||
this._queryInput = document.querySelector('#query');
|
this._queryInput = document.querySelector('#search-textbox');
|
||||||
this._introElement = document.querySelector('#intro');
|
this._introElement = document.querySelector('#intro');
|
||||||
this._clipboardMonitorEnableCheckbox = document.querySelector('#clipboard-monitor-enable');
|
this._clipboardMonitorEnableCheckbox = document.querySelector('#clipboard-monitor-enable');
|
||||||
this._wanakanaEnableCheckbox = document.querySelector('#wanakana-enable');
|
this._wanakanaEnableCheckbox = document.querySelector('#wanakana-enable');
|
||||||
|
this._queryInputEvents = new EventListenerCollection();
|
||||||
|
this._wanakanaEnabled = false;
|
||||||
this._isPrepared = false;
|
this._isPrepared = false;
|
||||||
this._introVisible = true;
|
this._introVisible = true;
|
||||||
this._introAnimationTimer = null;
|
this._introAnimationTimer = null;
|
||||||
@ -42,7 +44,7 @@ class DisplaySearch extends Display {
|
|||||||
});
|
});
|
||||||
this._onKeyDownIgnoreKeys = new Map([
|
this._onKeyDownIgnoreKeys = new Map([
|
||||||
['ANY_MOD', new Set([
|
['ANY_MOD', new Set([
|
||||||
'Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageDown', 'PageUp', 'Home', 'End',
|
'Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'PageDown', 'PageUp', 'Home', 'End', 'Enter',
|
||||||
'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10',
|
'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10',
|
||||||
'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20',
|
'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20',
|
||||||
'F21', 'F22', 'F23', 'F24'
|
'F21', 'F22', 'F23', 'F24'
|
||||||
@ -71,22 +73,16 @@ class DisplaySearch extends Display {
|
|||||||
this.queryParserVisible = true;
|
this.queryParserVisible = true;
|
||||||
this.setHistorySettings({useBrowserHistory: true});
|
this.setHistorySettings({useBrowserHistory: true});
|
||||||
|
|
||||||
const options = this.getOptions();
|
const enableWanakana = !!this.getOptions().general.enableWanakana;
|
||||||
if (options.general.enableWanakana === true) {
|
this._wanakanaEnableCheckbox.checked = enableWanakana;
|
||||||
this._wanakanaEnableCheckbox.checked = true;
|
this._setWanakanaEnabled(enableWanakana);
|
||||||
wanakana.bind(this._queryInput);
|
|
||||||
} else {
|
|
||||||
this._wanakanaEnableCheckbox.checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._searchButton.addEventListener('click', this._onSearch.bind(this), false);
|
this._searchButton.addEventListener('click', this._onSearch.bind(this), false);
|
||||||
this._queryInput.addEventListener('input', this._onSearchInput.bind(this), false);
|
|
||||||
this._wanakanaEnableCheckbox.addEventListener('change', this._onWanakanaEnableChange.bind(this));
|
this._wanakanaEnableCheckbox.addEventListener('change', this._onWanakanaEnableChange.bind(this));
|
||||||
window.addEventListener('copy', this._onCopy.bind(this));
|
window.addEventListener('copy', this._onCopy.bind(this));
|
||||||
this._clipboardMonitor.on('change', this._onExternalSearchUpdate.bind(this));
|
this._clipboardMonitor.on('change', this._onExternalSearchUpdate.bind(this));
|
||||||
this._clipboardMonitorEnableCheckbox.addEventListener('change', this._onClipboardMonitorEnableChange.bind(this));
|
this._clipboardMonitorEnableCheckbox.addEventListener('change', this._onClipboardMonitorEnableChange.bind(this));
|
||||||
|
|
||||||
this._updateSearchButton();
|
|
||||||
this._onModeChange();
|
this._onModeChange();
|
||||||
|
|
||||||
await this._prepareNestedPopups();
|
await this._prepareNestedPopups();
|
||||||
@ -141,7 +137,7 @@ class DisplaySearch extends Display {
|
|||||||
}
|
}
|
||||||
|
|
||||||
postProcessQuery(query) {
|
postProcessQuery(query) {
|
||||||
if (this._isWanakanaEnabled()) {
|
if (this._wanakanaEnabled) {
|
||||||
try {
|
try {
|
||||||
query = wanakana.toKana(query);
|
query = wanakana.toKana(query);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -173,28 +169,27 @@ class DisplaySearch extends Display {
|
|||||||
if (typeof source !== 'string') { source = ''; }
|
if (typeof source !== 'string') { source = ''; }
|
||||||
|
|
||||||
this._queryInput.value = source;
|
this._queryInput.value = source;
|
||||||
|
this._updateSearchHeight();
|
||||||
this._setIntroVisible(!valid, animate);
|
this._setIntroVisible(!valid, animate);
|
||||||
this._updateSearchButton();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSearchInput() {
|
_onSearchInput() {
|
||||||
this._updateSearchButton();
|
this._updateSearchHeight();
|
||||||
|
|
||||||
const queryElementRect = this._queryInput.getBoundingClientRect();
|
|
||||||
if (queryElementRect.top < 0 || queryElementRect.bottom > window.innerHeight) {
|
|
||||||
this._queryInput.scrollIntoView();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onSearchKeydown(e) {
|
||||||
|
if (e.code !== 'Enter' || e.shiftKey) { return; }
|
||||||
|
|
||||||
|
// Search
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
e.currentTarget.blur();
|
||||||
|
this._search();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onSearch(e) {
|
_onSearch(e) {
|
||||||
if (this._queryInput === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
this._search();
|
||||||
const query = this._queryInput.value;
|
|
||||||
this._onSearchQueryUpdated(query, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCopy() {
|
_onCopy() {
|
||||||
@ -228,11 +223,7 @@ class DisplaySearch extends Display {
|
|||||||
|
|
||||||
_onWanakanaEnableChange(e) {
|
_onWanakanaEnableChange(e) {
|
||||||
const value = e.target.checked;
|
const value = e.target.checked;
|
||||||
if (value) {
|
this._setWanakanaEnabled(value);
|
||||||
wanakana.bind(this._queryInput);
|
|
||||||
} else {
|
|
||||||
wanakana.unbind(this._queryInput);
|
|
||||||
}
|
|
||||||
api.modifySettings([{
|
api.modifySettings([{
|
||||||
action: 'set',
|
action: 'set',
|
||||||
path: 'general.enableWanakana',
|
path: 'general.enableWanakana',
|
||||||
@ -254,8 +245,22 @@ class DisplaySearch extends Display {
|
|||||||
this._updateClipboardMonitorEnabled();
|
this._updateClipboardMonitorEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
_isWanakanaEnabled() {
|
_setWanakanaEnabled(enabled) {
|
||||||
return this._wanakanaEnableCheckbox !== null && this._wanakanaEnableCheckbox.checked;
|
const input = this._queryInput;
|
||||||
|
this._queryInputEvents.removeAllEventListeners();
|
||||||
|
|
||||||
|
this._queryInputEvents.addEventListener(input, 'keydown', this._onSearchKeydown.bind(this), false);
|
||||||
|
|
||||||
|
if (this._wanakanaEnabled !== enabled) {
|
||||||
|
this._wanakanaEnabled = enabled;
|
||||||
|
if (enabled) {
|
||||||
|
wanakana.bind(input);
|
||||||
|
} else {
|
||||||
|
wanakana.unbind(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._queryInputEvents.addEventListener(input, 'input', this._onSearchInput.bind(this), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setIntroVisible(visible, animate) {
|
_setIntroVisible(visible, animate) {
|
||||||
@ -314,10 +319,6 @@ class DisplaySearch extends Display {
|
|||||||
this._introElement.style.height = '0';
|
this._introElement.style.height = '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateSearchButton() {
|
|
||||||
this._searchButton.disabled = this._introVisible && (this._queryInput === null || this._queryInput.value.length === 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
async _prepareNestedPopups() {
|
async _prepareNestedPopups() {
|
||||||
let complete = false;
|
let complete = false;
|
||||||
|
|
||||||
@ -388,4 +389,18 @@ class DisplaySearch extends Display {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_search() {
|
||||||
|
const query = this._queryInput.value;
|
||||||
|
this._onSearchQueryUpdated(query, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateSearchHeight() {
|
||||||
|
const node = this._queryInput;
|
||||||
|
const {scrollHeight} = node;
|
||||||
|
const currentHeight = node.getBoundingClientRect().height;
|
||||||
|
if (scrollHeight >= currentHeight - 1) {
|
||||||
|
node.style.height = `${scrollHeight}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" data-yomichan-page="search">
|
<html lang="en" data-yomichan-page="search">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<title>Yomichan Search</title>
|
<title>Yomichan Search</title>
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon16.png" sizes="16x16">
|
<link rel="icon" type="image/png" href="/mixed/img/icon16.png" sizes="16x16">
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon19.png" sizes="19x19">
|
<link rel="icon" type="image/png" href="/mixed/img/icon19.png" sizes="19x19">
|
||||||
@ -11,95 +11,85 @@
|
|||||||
<link rel="icon" type="image/png" href="/mixed/img/icon48.png" sizes="48x48">
|
<link rel="icon" type="image/png" href="/mixed/img/icon48.png" sizes="48x48">
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon64.png" sizes="64x64">
|
<link rel="icon" type="image/png" href="/mixed/img/icon64.png" sizes="64x64">
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon128.png" sizes="128x128">
|
<link rel="icon" type="image/png" href="/mixed/img/icon128.png" sizes="128x128">
|
||||||
<link rel="stylesheet" type="text/css" href="/mixed/lib/bootstrap/css/bootstrap.min.css">
|
<link rel="stylesheet" type="text/css" href="/mixed/css/search.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/mixed/lib/bootstrap/css/bootstrap-theme.min.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="/mixed/css/display.css">
|
<link rel="stylesheet" type="text/css" href="/mixed/css/display.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
|
||||||
<div id="intro" style="overflow: hidden;">
|
<div class="content"><div class="content-center">
|
||||||
<div class="page-header">
|
|
||||||
|
<div id="intro">
|
||||||
<h1>Yomichan Search</h1>
|
<h1>Yomichan Search</h1>
|
||||||
</div>
|
</div>
|
||||||
<p style="margin-bottom: 0;">Search your installed dictionaries by entering a Japanese expression into the field below.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="search-input">
|
<div class="scan-disable">
|
||||||
<div class="input-group" style="padding-top: 20px;">
|
<div class="search-options">
|
||||||
<span title="Enable kana input method" class="input-group-text">
|
<label class="search-option">
|
||||||
<input type="checkbox" id="wanakana-enable" class="icon-checkbox" />
|
<label class="toggle"><input type="checkbox" id="wanakana-enable"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
||||||
<label for="wanakana-enable" class="scan-disable">あ</label>
|
<span class="search-option-label">Automatic kana conversion</span>
|
||||||
</span>
|
</label>
|
||||||
<span title="Enable clipboard monitor" class="input-group-text">
|
<label class="search-option">
|
||||||
<input type="checkbox" id="clipboard-monitor-enable" class="icon-checkbox" />
|
<label class="toggle"><input type="checkbox" id="clipboard-monitor-enable"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
|
||||||
<label for="clipboard-monitor-enable"><span class="glyphicon glyphicon-paste"></span></label>
|
<span class="search-option-label">Clipboard monitor</span>
|
||||||
</span>
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="search-textbox-container">
|
||||||
|
<textarea id="search-textbox" placeholder="Input a term, expression, sentence, or block of text" autocomplete="false" autofocus></textarea>
|
||||||
|
<button id="search-button"><span class="icon-button-icon" data-icon="magnifying-glass"></span></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="input-group">
|
|
||||||
<input type="text" class="form-control" placeholder="Search for..." id="query" autofocus>
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<input type="submit" class="btn btn-default form-control" id="search" value="Search">
|
|
||||||
</span>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="spinner" hidden><img src="/mixed/img/spinner.gif"></div>
|
<div id="spinner" hidden><img src="/mixed/img/spinner.gif"></div>
|
||||||
|
|
||||||
<div class="scan-disable" id="query-parser-container">
|
<div class="scan-disable" id="query-parser-container">
|
||||||
<div id="query-parser-select-container" class="input-group"></div>
|
<div id="query-parser-select-container"></div>
|
||||||
<div id="query-parser-content"></div>
|
<div id="query-parser-content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<div id="definitions"></div>
|
||||||
|
|
||||||
<div id="navigation-header" class="navigation-header" hidden><div class="navigation-header-actions">
|
|
||||||
<button class="action-button action-previous" data-icon="source-term" title="Source term (Alt + B)"></button>
|
|
||||||
<button class="action-button action-next" data-icon="source-term" title="Next term (Alt + F)"></button>
|
|
||||||
</div></div><div class="navigation-header-spacer"></div>
|
|
||||||
|
|
||||||
<div id="content"></div>
|
|
||||||
|
|
||||||
<div id="no-results" hidden>
|
<div id="no-results" hidden>
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<p>No results found.</p>
|
<p>No results found.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="/mixed/lib/wanakana.min.js"></script>
|
</div></div>
|
||||||
|
|
||||||
<script src="/mixed/js/core.js"></script>
|
<script src="/mixed/lib/wanakana.min.js"></script>
|
||||||
<script src="/mixed/js/yomichan.js"></script>
|
|
||||||
<script src="/mixed/js/comm.js"></script>
|
|
||||||
<script src="/mixed/js/api.js"></script>
|
|
||||||
<script src="/mixed/js/japanese.js"></script>
|
|
||||||
|
|
||||||
<script src="/mixed/js/cache-map.js"></script>
|
<script src="/mixed/js/core.js"></script>
|
||||||
<script src="/mixed/js/document-util.js"></script>
|
<script src="/mixed/js/yomichan.js"></script>
|
||||||
<script src="/fg/js/dom-text-scanner.js"></script>
|
<script src="/mixed/js/comm.js"></script>
|
||||||
<script src="/fg/js/text-source-range.js"></script>
|
<script src="/mixed/js/api.js"></script>
|
||||||
<script src="/fg/js/text-source-element.js"></script>
|
<script src="/mixed/js/japanese.js"></script>
|
||||||
<script src="/mixed/js/audio-system.js"></script>
|
|
||||||
<script src="/mixed/js/dictionary-data-util.js"></script>
|
|
||||||
<script src="/mixed/js/display.js"></script>
|
|
||||||
<script src="/mixed/js/display-generator.js"></script>
|
|
||||||
<script src="/mixed/js/display-history.js"></script>
|
|
||||||
<script src="/mixed/js/dynamic-loader.js"></script>
|
|
||||||
<script src="/mixed/js/media-loader.js"></script>
|
|
||||||
<script src="/mixed/js/scroll.js"></script>
|
|
||||||
<script src="/mixed/js/text-scanner.js"></script>
|
|
||||||
<script src="/mixed/js/html-template-collection.js"></script>
|
|
||||||
<script src="/mixed/js/text-to-speech-audio.js"></script>
|
|
||||||
|
|
||||||
<script src="/bg/js/anki-note-builder.js"></script>
|
<script src="/mixed/js/cache-map.js"></script>
|
||||||
<script src="/bg/js/template-renderer-proxy.js"></script>
|
<script src="/mixed/js/document-util.js"></script>
|
||||||
|
<script src="/fg/js/dom-text-scanner.js"></script>
|
||||||
|
<script src="/fg/js/text-source-range.js"></script>
|
||||||
|
<script src="/fg/js/text-source-element.js"></script>
|
||||||
|
<script src="/mixed/js/audio-system.js"></script>
|
||||||
|
<script src="/mixed/js/dictionary-data-util.js"></script>
|
||||||
|
<script src="/mixed/js/display.js"></script>
|
||||||
|
<script src="/mixed/js/display-generator.js"></script>
|
||||||
|
<script src="/mixed/js/display-history.js"></script>
|
||||||
|
<script src="/mixed/js/dynamic-loader.js"></script>
|
||||||
|
<script src="/mixed/js/media-loader.js"></script>
|
||||||
|
<script src="/mixed/js/scroll.js"></script>
|
||||||
|
<script src="/mixed/js/text-scanner.js"></script>
|
||||||
|
<script src="/mixed/js/html-template-collection.js"></script>
|
||||||
|
<script src="/mixed/js/text-to-speech-audio.js"></script>
|
||||||
|
|
||||||
<script src="/bg/js/query-parser-generator.js"></script>
|
<script src="/bg/js/anki-note-builder.js"></script>
|
||||||
<script src="/bg/js/query-parser.js"></script>
|
<script src="/bg/js/template-renderer-proxy.js"></script>
|
||||||
<script src="/bg/js/clipboard-monitor.js"></script>
|
|
||||||
<script src="/bg/js/search.js"></script>
|
|
||||||
|
|
||||||
<script src="/bg/js/search-main.js"></script>
|
<script src="/bg/js/query-parser-generator.js"></script>
|
||||||
</body>
|
<script src="/bg/js/query-parser.js"></script>
|
||||||
|
<script src="/bg/js/clipboard-monitor.js"></script>
|
||||||
|
<script src="/bg/js/search.js"></script>
|
||||||
|
|
||||||
|
<script src="/bg/js/search-main.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" data-yomichan-page="float">
|
<html lang="en" data-yomichan-page="float">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
<title>Yomichan Search</title>
|
<title>Yomichan Search</title>
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon16.png" sizes="16x16">
|
<link rel="icon" type="image/png" href="/mixed/img/icon16.png" sizes="16x16">
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon19.png" sizes="19x19">
|
<link rel="icon" type="image/png" href="/mixed/img/icon19.png" sizes="19x19">
|
||||||
@ -11,9 +11,10 @@
|
|||||||
<link rel="icon" type="image/png" href="/mixed/img/icon48.png" sizes="48x48">
|
<link rel="icon" type="image/png" href="/mixed/img/icon48.png" sizes="48x48">
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon64.png" sizes="64x64">
|
<link rel="icon" type="image/png" href="/mixed/img/icon64.png" sizes="64x64">
|
||||||
<link rel="icon" type="image/png" href="/mixed/img/icon128.png" sizes="128x128">
|
<link rel="icon" type="image/png" href="/mixed/img/icon128.png" sizes="128x128">
|
||||||
<link rel="stylesheet" href="/mixed/css/display.css">
|
<link rel="stylesheet" type="text/css" href="/mixed/css/display.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="spinner" hidden><img src="/mixed/img/spinner.gif"></div>
|
<div id="spinner" hidden><img src="/mixed/img/spinner.gif"></div>
|
||||||
|
|
||||||
<div id="navigation-header" class="navigation-header" hidden><div class="navigation-header-actions">
|
<div id="navigation-header" class="navigation-header" hidden><div class="navigation-header-actions">
|
||||||
@ -44,37 +45,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/mixed/js/core.js"></script>
|
<script src="/mixed/js/core.js"></script>
|
||||||
<script src="/mixed/js/yomichan.js"></script>
|
<script src="/mixed/js/yomichan.js"></script>
|
||||||
<script src="/mixed/js/comm.js"></script>
|
<script src="/mixed/js/comm.js"></script>
|
||||||
<script src="/mixed/js/api.js"></script>
|
<script src="/mixed/js/api.js"></script>
|
||||||
<script src="/mixed/js/japanese.js"></script>
|
<script src="/mixed/js/japanese.js"></script>
|
||||||
|
|
||||||
<script src="/mixed/js/cache-map.js"></script>
|
<script src="/mixed/js/cache-map.js"></script>
|
||||||
<script src="/mixed/js/document-util.js"></script>
|
<script src="/mixed/js/document-util.js"></script>
|
||||||
<script src="/fg/js/dom-text-scanner.js"></script>
|
<script src="/fg/js/dom-text-scanner.js"></script>
|
||||||
<script src="/fg/js/text-source-range.js"></script>
|
<script src="/fg/js/text-source-range.js"></script>
|
||||||
<script src="/fg/js/text-source-element.js"></script>
|
<script src="/fg/js/text-source-element.js"></script>
|
||||||
<script src="/mixed/js/audio-system.js"></script>
|
<script src="/mixed/js/audio-system.js"></script>
|
||||||
<script src="/mixed/js/dictionary-data-util.js"></script>
|
<script src="/mixed/js/dictionary-data-util.js"></script>
|
||||||
<script src="/mixed/js/display.js"></script>
|
<script src="/mixed/js/display.js"></script>
|
||||||
<script src="/mixed/js/display-generator.js"></script>
|
<script src="/mixed/js/display-generator.js"></script>
|
||||||
<script src="/mixed/js/display-history.js"></script>
|
<script src="/mixed/js/display-history.js"></script>
|
||||||
<script src="/mixed/js/dynamic-loader.js"></script>
|
<script src="/mixed/js/dynamic-loader.js"></script>
|
||||||
<script src="/mixed/js/frame-endpoint.js"></script>
|
<script src="/mixed/js/frame-endpoint.js"></script>
|
||||||
<script src="/mixed/js/media-loader.js"></script>
|
<script src="/mixed/js/media-loader.js"></script>
|
||||||
<script src="/mixed/js/scroll.js"></script>
|
<script src="/mixed/js/scroll.js"></script>
|
||||||
<script src="/mixed/js/text-scanner.js"></script>
|
<script src="/mixed/js/text-scanner.js"></script>
|
||||||
<script src="/mixed/js/html-template-collection.js"></script>
|
<script src="/mixed/js/html-template-collection.js"></script>
|
||||||
<script src="/mixed/js/text-to-speech-audio.js"></script>
|
<script src="/mixed/js/text-to-speech-audio.js"></script>
|
||||||
|
|
||||||
<script src="/bg/js/anki-note-builder.js"></script>
|
<script src="/bg/js/anki-note-builder.js"></script>
|
||||||
<script src="/bg/js/template-renderer-proxy.js"></script>
|
<script src="/bg/js/template-renderer-proxy.js"></script>
|
||||||
|
|
||||||
<script src="/bg/js/query-parser-generator.js"></script>
|
<script src="/bg/js/query-parser-generator.js"></script>
|
||||||
<script src="/bg/js/query-parser.js"></script>
|
<script src="/bg/js/query-parser.js"></script>
|
||||||
<script src="/fg/js/float.js"></script>
|
<script src="/fg/js/float.js"></script>
|
||||||
|
|
||||||
<script src="/fg/js/float-main.js"></script>
|
<script src="/fg/js/float-main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
class DisplayFloat extends Display {
|
class DisplayFloat extends Display {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(document.querySelector('#spinner'), document.querySelector('#definitions'));
|
super();
|
||||||
this._nestedPopupsPrepared = false;
|
this._nestedPopupsPrepared = false;
|
||||||
this._frameEndpoint = new FrameEndpoint();
|
this._frameEndpoint = new FrameEndpoint();
|
||||||
this._windowMessageHandlers = new Map([
|
this._windowMessageHandlers = new Map([
|
||||||
|
@ -187,23 +187,6 @@ h2 {
|
|||||||
* Search page
|
* Search page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.icon-checkbox {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-checkbox+label {
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 1.6em;
|
|
||||||
padding: 0.1em;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-checkbox:checked+label {
|
|
||||||
/* Invert colors */
|
|
||||||
background-color: var(--default-text-color);
|
|
||||||
color: var(--background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
#query-parser-content {
|
#query-parser-content {
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
|
326
ext/mixed/css/search.css
Normal file
326
ext/mixed/css/search.css
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Yomichan Authors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Variables */
|
||||||
|
:root {
|
||||||
|
--main-content-size: 700px;
|
||||||
|
--main-content-padding: 10px;
|
||||||
|
--shadow-color: rgba(0, 0, 0, 0.185);
|
||||||
|
--shadow-vertical: 0 1px 4px 0 var(--shadow-color), 0 2px 2px 0 var(--shadow-color);
|
||||||
|
|
||||||
|
--font-size-default: 14px;
|
||||||
|
--line-height-default: calc(20 / 14);
|
||||||
|
--thin-border-size: 1px;
|
||||||
|
--toggle-size: 16px;
|
||||||
|
|
||||||
|
--textarea-line-height: 1.25em;
|
||||||
|
--textarea-padding: 0.5em;
|
||||||
|
|
||||||
|
--animation-duration: 0s;
|
||||||
|
--animation-duration2: calc(var(--animation-duration) * 2);
|
||||||
|
|
||||||
|
--text-color-default: #222222;
|
||||||
|
--background-color: #ffffff;
|
||||||
|
--background-color-light: #ffffff;
|
||||||
|
--input-background-color: #f2f2f2;
|
||||||
|
--input-background-color-dark: #dddddd;
|
||||||
|
--input-background-color-darker: #cccccc;
|
||||||
|
--separator-color1: #cccccc;
|
||||||
|
--button-icon-color: #333333;
|
||||||
|
--toggle-track-color: #cccccc;
|
||||||
|
--toggle-knob-color: #ffffff;
|
||||||
|
--selectable-indicator-color: rgba(160, 160, 160, 0.25);
|
||||||
|
--disabled-color: #aaaaaa;
|
||||||
|
--disabled-color-light: #dddddd;
|
||||||
|
--disabled-color-lighter: #eeeeee;
|
||||||
|
--accent-color: #1a73e8;
|
||||||
|
--accent-color-lighter: #8db9f4;
|
||||||
|
--accent-color-transparent25: rgba(28, 116, 233, 0.25);
|
||||||
|
}
|
||||||
|
:root[data-loaded=true] {
|
||||||
|
--animation-duration: 0.125s;
|
||||||
|
}
|
||||||
|
:root[data-yomichan-theme=dark] {
|
||||||
|
--text-color-default: #d8d8d8;
|
||||||
|
--background-color: #1e1e1e;
|
||||||
|
--shadow-color: rgba(255, 255, 255, 0.185);
|
||||||
|
--separator-color1: #cccccc;
|
||||||
|
--input-background-color: #2f2f2f;
|
||||||
|
--input-background-color-dark: #383838;
|
||||||
|
--input-background-color-darker: #484848;
|
||||||
|
--selectable-indicator-color: rgba(100, 100, 100, 0.25);
|
||||||
|
--button-icon-color: #cccccc;
|
||||||
|
--disabled-color: #444444;
|
||||||
|
--disabled-color-light: #585858;
|
||||||
|
--disabled-color-lighter: #777777;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common styles */
|
||||||
|
:root {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: var(--background-color);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-size: var(--font-size-default);
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
color: var(--text-color-default);
|
||||||
|
line-height: var(--line-height-default);
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
line-height: 1.5em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.25em 0 0;
|
||||||
|
font-weight: normal;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-bottom: var(--thin-border-size) solid var(--separator-color1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Material design toggle switch */
|
||||||
|
label.toggle {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.toggle {
|
||||||
|
font-size: var(--toggle-size);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox] {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
display: block;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
}
|
||||||
|
.toggle-body {
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 2em;
|
||||||
|
height: 1em;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.toggle-track {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 0.125em;
|
||||||
|
right: 0.125em;
|
||||||
|
top: 0.125em;
|
||||||
|
bottom: 0.125em;
|
||||||
|
background-color: var(--toggle-track-color);
|
||||||
|
border-radius: 0.4375em;
|
||||||
|
transition: background-color var(--animation-duration) ease-in-out;
|
||||||
|
}
|
||||||
|
.toggle-knob {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
background-color: var(--toggle-knob-color);
|
||||||
|
border-radius: 0.5em;
|
||||||
|
box-shadow: var(--shadow-vertical);
|
||||||
|
transition: transform var(--animation-duration) ease-in-out,
|
||||||
|
background-color var(--animation-duration) ease-in-out;
|
||||||
|
}
|
||||||
|
.toggle-body>.toggle-knob::after {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
content: "";
|
||||||
|
left: -0.75em;
|
||||||
|
top: -0.75em;
|
||||||
|
right: -0.75em;
|
||||||
|
bottom: -0.75em;
|
||||||
|
border-radius: 2.5em;
|
||||||
|
background-color: var(--selectable-indicator-color);
|
||||||
|
pointer-events: none;
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transition: transform 0s ease-in-out var(--animation-duration2),
|
||||||
|
background-color var(--animation-duration2) ease-in-out,
|
||||||
|
opacity var(--animation-duration2) ease-in-out,
|
||||||
|
visibility 0s ease-in-out var(--animation-duration2);
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:focus:not(:disabled)+.toggle-body>.toggle-knob::after,
|
||||||
|
.toggle:active>input[type=checkbox]:not(:disabled)+.toggle-body>.toggle-knob::after {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
transition: transform var(--animation-duration2) ease-in-out,
|
||||||
|
background-color var(--animation-duration2) ease-in-out,
|
||||||
|
opacity var(--animation-duration2) ease-in-out,
|
||||||
|
visibility var(--animation-duration2) ease-in-out;
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:focus+.toggle-body>.toggle-knob::after {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.toggle:active>input[type=checkbox]:focus+.toggle-body>.toggle-knob::after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:checked+.toggle-body>.toggle-knob {
|
||||||
|
transform: translateX(1em);
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:checked:not(:disabled)+.toggle-body>.toggle-track {
|
||||||
|
background-color: var(--accent-color-lighter);
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:checked:not(:disabled)+.toggle-body>.toggle-knob {
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:focus:checked:not(:disabled)+.toggle-body>.toggle-knob::after,
|
||||||
|
.toggle:active>input[type=checkbox]:checked:not(:disabled)+.toggle-body>.toggle-knob::after {
|
||||||
|
background-color: var(--accent-color-transparent25);
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:disabled+.toggle-body {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:disabled+.toggle-body>.toggle-track {
|
||||||
|
background-color: var(--disabled-color-light);
|
||||||
|
}
|
||||||
|
.toggle>input[type=checkbox]:disabled+.toggle-body>.toggle-knob {
|
||||||
|
background-color: var(--disabled-color-lighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content layout */
|
||||||
|
.content {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.content-center {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: var(--main-content-size);
|
||||||
|
padding: 0 var(--main-content-padding);
|
||||||
|
max-width: var(--main-content-size);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search bar */
|
||||||
|
.search-textbox-container {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
width: 100%;
|
||||||
|
align-items: stretch;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
#search-textbox {
|
||||||
|
color: var(--text-color-default);
|
||||||
|
flex: 1 1 auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: var(--textarea-padding);
|
||||||
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
background-color: var(--input-background-color);
|
||||||
|
border-radius: 0;
|
||||||
|
line-height: var(--textarea-line-height);
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(var(--textarea-line-height) + var(--textarea-padding) * 2);
|
||||||
|
min-height: calc(var(--textarea-line-height) + var(--textarea-padding) * 2);
|
||||||
|
max-height: calc(var(--textarea-line-height) * 10 + var(--textarea-padding) * 2);
|
||||||
|
resize: vertical;
|
||||||
|
font-size: var(--font-size-default);
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
color: var(--text-color-default);
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
#search-button {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
position: relative;
|
||||||
|
width: 2.5em;
|
||||||
|
background-color: var(--input-background-color);
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
transition: background-color var(--animation-duration) ease-in-out;
|
||||||
|
}
|
||||||
|
#search-button:hover,
|
||||||
|
#search-button:focus {
|
||||||
|
background-color: var(--input-background-color-dark);
|
||||||
|
}
|
||||||
|
#search-button:active {
|
||||||
|
background-color: var(--input-background-color-darker);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button-icon {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: var(--button-icon-color);
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center center;
|
||||||
|
mask-mode: alpha;
|
||||||
|
-webkit-mask-repeat: no-repeat;
|
||||||
|
-webkit-mask-position: center center;
|
||||||
|
-webkit-mask-mode: alpha;
|
||||||
|
}
|
||||||
|
.icon-button-icon[data-icon=magnifying-glass] {
|
||||||
|
mask-image: url(/mixed/img/magnifying-glass.svg);
|
||||||
|
-webkit-mask-image: url(/mixed/img/magnifying-glass.svg);
|
||||||
|
mask-size: 16px 16px;
|
||||||
|
-webkit-mask-size: 16px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search options */
|
||||||
|
.search-options {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
margin: 0.5em -1em;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.search-option {
|
||||||
|
display: flex;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
margin: 0.5em 1em;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.search-option-label {
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search styles */
|
||||||
|
#intro {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#intro>p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#query-parser-content:not(:empty) {
|
||||||
|
border-bottom: var(--thin-border-size) solid var(--separator-color1);
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
}
|
@ -32,10 +32,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class Display extends EventDispatcher {
|
class Display extends EventDispatcher {
|
||||||
constructor(spinner, container) {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._spinner = spinner;
|
this._spinner = document.querySelector('#spinner');
|
||||||
this._container = container;
|
this._container = document.querySelector('#definitions');
|
||||||
this._definitions = [];
|
this._definitions = [];
|
||||||
this._optionsContext = {depth: 0, url: window.location.href};
|
this._optionsContext = {depth: 0, url: window.location.href};
|
||||||
this._options = null;
|
this._options = null;
|
||||||
@ -804,7 +804,10 @@ class Display extends EventDispatcher {
|
|||||||
|
|
||||||
async _setContentTermsOrKanji(token, isTerms, urlSearchParams, eventArgs) {
|
async _setContentTermsOrKanji(token, isTerms, urlSearchParams, eventArgs) {
|
||||||
let source = urlSearchParams.get('query');
|
let source = urlSearchParams.get('query');
|
||||||
if (!source) { return false; }
|
if (!source) {
|
||||||
|
this._setQueryParserText('');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let {state, content} = this._history;
|
let {state, content} = this._history;
|
||||||
let changeHistory = false;
|
let changeHistory = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user