diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-11-08 12:34:23 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-08 12:34:23 -0500 |
commit | 8cf10d685d52d5ae75d65c4aea4adcb6d101e9a4 (patch) | |
tree | 3a1874942370917e328976854c5a5c7352d9e085 /ext/bg | |
parent | db9ec4c4495404ad3ebc9ce56866c3631cedf8dc (diff) |
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
Diffstat (limited to 'ext/bg')
-rw-r--r-- | ext/bg/js/search-main.js | 1 | ||||
-rw-r--r-- | ext/bg/js/search.js | 91 | ||||
-rw-r--r-- | ext/bg/search.html | 166 |
3 files changed, 132 insertions, 126 deletions
diff --git a/ext/bg/js/search-main.js b/ext/bg/js/search-main.js index cf9282fd..07130631 100644 --- a/ext/bg/js/search-main.js +++ b/ext/bg/js/search-main.js @@ -28,6 +28,7 @@ const displaySearch = new DisplaySearch(); await displaySearch.prepare(); + document.documentElement.dataset.loaded = 'true'; yomichan.ready(); } catch (e) { yomichan.logError(e); diff --git a/ext/bg/js/search.js b/ext/bg/js/search.js index af88bb76..bd840981 100644 --- a/ext/bg/js/search.js +++ b/ext/bg/js/search.js @@ -25,12 +25,14 @@ class DisplaySearch extends Display { constructor() { - super(document.querySelector('#spinner'), document.querySelector('#content')); - this._searchButton = document.querySelector('#search'); - this._queryInput = document.querySelector('#query'); + super(); + this._searchButton = document.querySelector('#search-button'); + this._queryInput = document.querySelector('#search-textbox'); this._introElement = document.querySelector('#intro'); this._clipboardMonitorEnableCheckbox = document.querySelector('#clipboard-monitor-enable'); this._wanakanaEnableCheckbox = document.querySelector('#wanakana-enable'); + this._queryInputEvents = new EventListenerCollection(); + this._wanakanaEnabled = false; this._isPrepared = false; this._introVisible = true; this._introAnimationTimer = null; @@ -42,7 +44,7 @@ class DisplaySearch extends Display { }); this._onKeyDownIgnoreKeys = new Map([ ['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', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24' @@ -71,22 +73,16 @@ class DisplaySearch extends Display { this.queryParserVisible = true; this.setHistorySettings({useBrowserHistory: true}); - const options = this.getOptions(); - if (options.general.enableWanakana === true) { - this._wanakanaEnableCheckbox.checked = true; - wanakana.bind(this._queryInput); - } else { - this._wanakanaEnableCheckbox.checked = false; - } + const enableWanakana = !!this.getOptions().general.enableWanakana; + this._wanakanaEnableCheckbox.checked = enableWanakana; + this._setWanakanaEnabled(enableWanakana); 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)); window.addEventListener('copy', this._onCopy.bind(this)); this._clipboardMonitor.on('change', this._onExternalSearchUpdate.bind(this)); this._clipboardMonitorEnableCheckbox.addEventListener('change', this._onClipboardMonitorEnableChange.bind(this)); - this._updateSearchButton(); this._onModeChange(); await this._prepareNestedPopups(); @@ -141,7 +137,7 @@ class DisplaySearch extends Display { } postProcessQuery(query) { - if (this._isWanakanaEnabled()) { + if (this._wanakanaEnabled) { try { query = wanakana.toKana(query); } catch (e) { @@ -173,28 +169,27 @@ class DisplaySearch extends Display { if (typeof source !== 'string') { source = ''; } this._queryInput.value = source; + this._updateSearchHeight(); this._setIntroVisible(!valid, animate); - this._updateSearchButton(); } _onSearchInput() { - this._updateSearchButton(); - - const queryElementRect = this._queryInput.getBoundingClientRect(); - if (queryElementRect.top < 0 || queryElementRect.bottom > window.innerHeight) { - this._queryInput.scrollIntoView(); - } + this._updateSearchHeight(); } - _onSearch(e) { - if (this._queryInput === null) { - return; - } + _onSearchKeydown(e) { + if (e.code !== 'Enter' || e.shiftKey) { return; } + // Search e.preventDefault(); + e.stopImmediatePropagation(); + e.currentTarget.blur(); + this._search(); + } - const query = this._queryInput.value; - this._onSearchQueryUpdated(query, true); + _onSearch(e) { + e.preventDefault(); + this._search(); } _onCopy() { @@ -228,11 +223,7 @@ class DisplaySearch extends Display { _onWanakanaEnableChange(e) { const value = e.target.checked; - if (value) { - wanakana.bind(this._queryInput); - } else { - wanakana.unbind(this._queryInput); - } + this._setWanakanaEnabled(value); api.modifySettings([{ action: 'set', path: 'general.enableWanakana', @@ -254,8 +245,22 @@ class DisplaySearch extends Display { this._updateClipboardMonitorEnabled(); } - _isWanakanaEnabled() { - return this._wanakanaEnableCheckbox !== null && this._wanakanaEnableCheckbox.checked; + _setWanakanaEnabled(enabled) { + 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) { @@ -314,10 +319,6 @@ class DisplaySearch extends Display { this._introElement.style.height = '0'; } - _updateSearchButton() { - this._searchButton.disabled = this._introVisible && (this._queryInput === null || this._queryInput.value.length === 0); - } - async _prepareNestedPopups() { 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`; + } + } } diff --git a/ext/bg/search.html b/ext/bg/search.html index 8df20581..6988a235 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -1,105 +1,95 @@ <!DOCTYPE html> <html lang="en" data-yomichan-page="search"> - <head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width,initial-scale=1" /> - <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/icon19.png" sizes="19x19"> - <link rel="icon" type="image/png" href="/mixed/img/icon32.png" sizes="32x32"> - <link rel="icon" type="image/png" href="/mixed/img/icon38.png" sizes="38x38"> - <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/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/lib/bootstrap/css/bootstrap-theme.min.css"> - <link rel="stylesheet" type="text/css" href="/mixed/css/display.css"> - </head> - <body> - <div class="container"> - <div id="intro" style="overflow: hidden;"> - <div class="page-header"> - <h1>Yomichan Search</h1> - </div> - <p style="margin-bottom: 0;">Search your installed dictionaries by entering a Japanese expression into the field below.</p> - </div> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <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/icon19.png" sizes="19x19"> + <link rel="icon" type="image/png" href="/mixed/img/icon32.png" sizes="32x32"> + <link rel="icon" type="image/png" href="/mixed/img/icon38.png" sizes="38x38"> + <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/icon128.png" sizes="128x128"> + <link rel="stylesheet" type="text/css" href="/mixed/css/search.css"> + <link rel="stylesheet" type="text/css" href="/mixed/css/display.css"> +</head> +<body> - <div class="search-input"> - <div class="input-group" style="padding-top: 20px;"> - <span title="Enable kana input method" class="input-group-text"> - <input type="checkbox" id="wanakana-enable" class="icon-checkbox" /> - <label for="wanakana-enable" class="scan-disable">あ</label> - </span> - <span title="Enable clipboard monitor" class="input-group-text"> - <input type="checkbox" id="clipboard-monitor-enable" class="icon-checkbox" /> - <label for="clipboard-monitor-enable"><span class="glyphicon glyphicon-paste"></span></label> - </span> - </div> +<div class="content"><div class="content-center"> - <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 id="intro"> + <h1>Yomichan Search</h1> + </div> - <div id="spinner" hidden><img src="/mixed/img/spinner.gif"></div> - - <div class="scan-disable" id="query-parser-container"> - <div id="query-parser-select-container" class="input-group"></div> - <div id="query-parser-content"></div> - </div> + <div class="scan-disable"> + <div class="search-options"> + <label class="search-option"> + <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> + <span class="search-option-label">Automatic kana conversion</span> + </label> + <label class="search-option"> + <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> + <span class="search-option-label">Clipboard monitor</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> - <hr> + <div id="spinner" hidden><img src="/mixed/img/spinner.gif"></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 class="scan-disable" id="query-parser-container"> + <div id="query-parser-select-container"></div> + <div id="query-parser-content"></div> + </div> - <div id="content"></div> + <div id="definitions"></div> - <div id="no-results" hidden> - <div class="entry"> - <p>No results found.</p> - </div> - </div> + <div id="no-results" hidden> + <div class="entry"> + <p>No results found.</p> </div> + </div> + +</div></div> + +<script src="/mixed/lib/wanakana.min.js"></script> - <script src="/mixed/lib/wanakana.min.js"></script> +<script src="/mixed/js/core.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/core.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/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="/mixed/js/cache-map.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/anki-note-builder.js"></script> +<script src="/bg/js/template-renderer-proxy.js"></script> - <script src="/bg/js/anki-note-builder.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.js"></script> +<script src="/bg/js/clipboard-monitor.js"></script> +<script src="/bg/js/search.js"></script> - <script src="/bg/js/query-parser-generator.js"></script> - <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> - <script src="/bg/js/search-main.js"></script> - </body> +</body> </html> |