diff options
| -rw-r--r-- | ext/css/material.css | 5 | ||||
| -rw-r--r-- | ext/images/monitor.svg | 1 | ||||
| -rw-r--r-- | ext/js/pages/settings/recommended-permissions-controller.js | 36 | ||||
| -rw-r--r-- | ext/js/pages/welcome-main.js | 4 | ||||
| -rw-r--r-- | ext/quick-start-guide.html | 104 | ||||
| -rw-r--r-- | ext/settings.html | 496 | ||||
| -rw-r--r-- | ext/welcome.html | 152 | 
7 files changed, 417 insertions, 381 deletions
| diff --git a/ext/css/material.css b/ext/css/material.css index bcc384ef..b1259294 100644 --- a/ext/css/material.css +++ b/ext/css/material.css @@ -211,7 +211,9 @@ body {  .danger-text {      color: var(--danger-color);  } - +.success-text { +    color: var(--success-color); +}  /* Icons */  .icon { @@ -277,6 +279,7 @@ body {  .icon[data-icon=accessibility]           { --icon-image: url(/images/accessibility.svg); }  .icon[data-icon=connection]              { --icon-image: url(/images/connection.svg); }  .icon[data-icon=external-link]           { --icon-image: url(/images/external-link.svg); } +.icon[data-icon=monitor]                 { --icon-image: url(/images/monitor.svg); }  .icon[data-icon=material-down-arrow] {      --icon-image: url(/images/material-down-arrow.svg);      --icon-size: var(--material-arrow-dimension2) var(--material-arrow-dimension1); diff --git a/ext/images/monitor.svg b/ext/images/monitor.svg new file mode 100644 index 00000000..b2fd82d6 --- /dev/null +++ b/ext/images/monitor.svg @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8"?><svg width="16px" height="16px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1090.5)"><path d="m0 1092.5v22h13v3.9997h-6v1.9999h18v-1.9999h-6v-3.9997h13v-22h-32zm2 2h28v17h-28v-17z" fill="#373737" stroke-width="1.1339"/></g></svg> diff --git a/ext/js/pages/settings/recommended-permissions-controller.js b/ext/js/pages/settings/recommended-permissions-controller.js index 8aff51c4..80572a9b 100644 --- a/ext/js/pages/settings/recommended-permissions-controller.js +++ b/ext/js/pages/settings/recommended-permissions-controller.js @@ -19,6 +19,7 @@  import {EventListenerCollection} from '../../core/event-listener-collection.js';  import {toError} from '../../core/to-error.js';  import {getAllPermissions, setPermissionsGranted} from '../../data/permissions-util.js'; +import {querySelectorNotNull} from '../../dom/query-selector.js';  export class RecommendedPermissionsController {      /** @@ -27,8 +28,8 @@ export class RecommendedPermissionsController {      constructor(settingsController) {          /** @type {import('./settings-controller.js').SettingsController} */          this._settingsController = settingsController; -        /** @type {?NodeListOf<HTMLInputElement>} */ -        this._originToggleNodes = null; +        /** @type {HTMLInputElement} */ +        this._originToggleNode = querySelectorNotNull(document, '#recommended-permissions-toggle');          /** @type {EventListenerCollection} */          this._eventListeners = new EventListenerCollection();          /** @type {?HTMLElement} */ @@ -37,11 +38,8 @@ export class RecommendedPermissionsController {      /** */      async prepare() { -        this._originToggleNodes = document.querySelectorAll('.recommended-permissions-toggle');          this._errorContainer = document.querySelector('#recommended-permissions-error'); -        for (const node of this._originToggleNodes) { -            node.addEventListener('change', this._onOriginToggleChange.bind(this), false); -        } +        this._originToggleNode.addEventListener('change', this._onOriginToggleChange.bind(this), false);          this._settingsController.on('permissionsChanged', this._onPermissionsChanged.bind(this));          await this._updatePermissions(); @@ -55,12 +53,8 @@ export class RecommendedPermissionsController {      _onPermissionsChanged({permissions}) {          this._eventListeners.removeAllEventListeners();          const originsSet = new Set(permissions.origins); -        if (this._originToggleNodes !== null) { -            for (const node of this._originToggleNodes) { -                const {origin} = node.dataset; -                node.checked = typeof origin === 'string' && originsSet.has(origin); -            } -        } +        const {origin} = this._originToggleNode.dataset; +        this._originToggleNode.checked = typeof origin === 'string' && originsSet.has(origin);      }      /** @@ -80,6 +74,7 @@ export class RecommendedPermissionsController {      async _updatePermissions() {          const permissions = await getAllPermissions();          this._onPermissionsChanged({permissions}); +        this._setWelcomePageText();      }      /** @@ -101,4 +96,21 @@ export class RecommendedPermissionsController {          await this._updatePermissions();          return true;      } + +    /** */ +    _setWelcomePageText() { +        /** @type {HTMLElement | null} */ +        this._textIfEnabled = document.querySelector('#permissions-enabled'); +        /** @type {HTMLElement | null} */ +        this._textIfDisabled = document.querySelector('#permissions-disabled'); +        if (this._textIfEnabled && this._textIfDisabled) { +            if (this._originToggleNode.checked) { +                this._textIfEnabled.hidden = false; +                this._textIfDisabled.hidden = true; +            } else { +                this._textIfEnabled.hidden = true; +                this._textIfDisabled.hidden = false; +            } +        } +    }  } diff --git a/ext/js/pages/welcome-main.js b/ext/js/pages/welcome-main.js index 23511dd6..7cb28cda 100644 --- a/ext/js/pages/welcome-main.js +++ b/ext/js/pages/welcome-main.js @@ -23,6 +23,7 @@ import {ExtensionContentController} from './common/extension-content-controller.  import {DictionaryController} from './settings/dictionary-controller.js';  import {DictionaryImportController} from './settings/dictionary-import-controller.js';  import {GenericSettingController} from './settings/generic-setting-controller.js'; +import {LanguagesController} from './settings/languages-controller.js';  import {ModalController} from './settings/modal-controller.js';  import {RecommendedPermissionsController} from './settings/recommended-permissions-controller.js';  import {ScanInputsSimpleController} from './settings/scan-inputs-simple-controller.js'; @@ -96,6 +97,9 @@ await Application.main(true, async (application) => {      const recommendedPermissionsController = new RecommendedPermissionsController(settingsController);      preparePromises.push(recommendedPermissionsController.prepare()); +    const languagesController = new LanguagesController(settingsController); +    preparePromises.push(languagesController.prepare()); +      await Promise.all(preparePromises);      document.documentElement.dataset.loaded = 'true'; diff --git a/ext/quick-start-guide.html b/ext/quick-start-guide.html new file mode 100644 index 00000000..46f461e2 --- /dev/null +++ b/ext/quick-start-guide.html @@ -0,0 +1,104 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +    <meta charset="UTF-8"> +    <meta name="viewport" content="width=device-width,initial-scale=1"> +    <title>Quick Start Guide</title> +    <link rel="icon" type="image/png" href="/images/icon16.png" sizes="16x16"> +    <link rel="icon" type="image/png" href="/images/icon19.png" sizes="19x19"> +    <link rel="icon" type="image/png" href="/images/icon32.png" sizes="32x32"> +    <link rel="icon" type="image/png" href="/images/icon38.png" sizes="38x38"> +    <link rel="icon" type="image/png" href="/images/icon48.png" sizes="48x48"> +    <link rel="icon" type="image/png" href="/images/icon64.png" sizes="64x64"> +    <link rel="icon" type="image/png" href="/images/icon128.png" sizes="128x128"> +    <link rel="stylesheet" type="text/css" href="/css/material.css"> +    <link rel="stylesheet" type="text/css" href="/css/settings.css"> +</head> +<body> + +<!-- Main content --> +<div class="content-outer"><div class="content"> +<div class="content-left"></div> +<div class="content-center"> + +    <span tabindex="-1" id="content-scroll-focus"></span> + +    <h1>Welcome to Yomitan!</h1> + +    <!-- Content --> +    <h2>Yomitan Quick Start Guide</h2> +    <div class="settings-group"> +        <div class="settings-item"> +            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                Clicking the <img src="/images/yomitan-icon.svg" class="inline-icon" alt=""> <em>Yomitan</em> button in the browser bar will open the quick-actions popup. +            </div></div></div> +            <div class="settings-item-children settings-item-children-group"> +                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                    The <img src="/images/cog.svg" class="inline-icon" alt=""> <em>cog</em> button will open the <a href="/settings.html" target="_blank" rel="noopener">Settings</a> page. +                </div></div></div></div> +                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                    The <img src="/images/magnifying-glass.svg" class="inline-icon" alt=""> <em>magnifying glass</em> button will open the <a href="/search.html" target="_blank" rel="noopener">Search</a> page, +                    enabling text and terms to be looked up using the installed dictionaries. +                    This can even be used in offline mode! +                </div></div></div></div> +                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                    The <img src="/images/question-mark-circle.svg" class="inline-icon" alt=""> <em>question mark</em> button will open the <a href="/info.html" target="_blank" rel="noopener">Information</a> page, +                    which has some helpful information and links about Yomitan. +                </div></div></div></div> +            </div> +        </div> +        <div class="settings-item"> +            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                Yomitan requires one or more dictionaries to be installed in order to look up terms, kanji, and other information. +                Several downloadable dictionaries can be found on the <a href="https://github.com/themoeway/yomitan/blob/master/docs/dictionaries.md#dictionaries" target="_blank" rel="noopener noreferrer">Yomitan homepage</a>. +                Dictionaries can be configured from the <a href="/settings.html#!dictionaries" rel="noopener">Settings</a> page. +            </div></div></div> +        </div> +        <div class="settings-item"> +            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                You can also import an exported collection of dictionaries from the <a href="/settings.html#!backup">Backup section of the Settings</a> page. + +                <br><br> + +                If you are migrating from Yomichan, you may be interested in importing your data into Yomitan. +                Please follow instructions from <a href="https://github.com/themoeway/yomitan/blob/master/docs/yomichan-migration.md#migrating-from-yomichan" target="_blank" rel="noopener noreferrer">Yomitan's README</a> for that. + +                <br><br> + +                If you are using or planning to use custom templates for Anki note creation, note that <a href="https://github.com/themoeway/yomitan/blob/master/docs/yomichan-migration.md#custom-templates" target="_blank" rel="noopener noreferrer">some syntax has changed from Yomichan and Yomibaba.</a> +                Please ensure that your custom templates are using the updated syntax. +            </div></div></div> +        </div> +        <div class="settings-item"> +            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                After dictionaries have been installed, webpage text can be scanned by moving the cursor while holding a modifier key. +                The default key is <kbd>Shift</kbd>, which can be disabled or configured below. +            </div></div></div> +            <div class="settings-item-children settings-item-children-group"> +                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                    Clicking the <img src="/images/play-audio.svg" class="inline-icon" alt=""> <em>speaker</em> button of an entry in the search results +                    will play an audio clip of a term's pronunciation using an online dictionary, if available. +                </div></div></div></div> +                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> +                    Clicking on a kanji character in a term's definition will show additional information about that character. +                    <span class="light">(Requires a kanji dictionary to be installed.)</span> +                </div></div></div></div> +            </div> +        </div> +        <a href="/welcome.html" rel="noopener" class="settings-item settings-item-button"><div class="settings-item-inner"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Back to Welcome page</div> +            </div> +            <div class="settings-item-right open-panel-button-container"> +                <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> +            </div> +        </div></a> +    </div> + +    <div class="footer-padding"></div> + +</div> +<div class="content-right"></div> +</div></div> +</body> +</html> diff --git a/ext/settings.html b/ext/settings.html index f32b8415..252de038 100644 --- a/ext/settings.html +++ b/ext/settings.html @@ -27,8 +27,9 @@              <a href="#!dictionaries"     class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="book"></span><span class="outline-item-left-warning-badge no-dictionaries-enabled-warning" hidden><div class="badge warning-badge"><span class="icon" data-icon="exclamation-point-short"></span></div></span></span><span class="outline-item-label">Dictionaries</span></a>              <a href="#!general"          class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="cog"></span></span><span class="outline-item-label">General</span></a>              <a href="#!scanning"         class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="scanning"></span></span><span class="outline-item-label">Scanning</span></a> -            <a href="#!popup"            class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="popup"></span></span><span class="outline-item-label">Popup</span></a> -            <a href="#!popup-appearance" class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="palette"></span></span><span class="outline-item-label">Appearance</span></a> +            <a href="#!popup"            class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="popup"></span></span><span class="outline-item-label">Popup Behavior</span></a> +            <a href="#!appearance"       class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="palette"></span></span><span class="outline-item-label">Appearance</span></a> +            <a href="#!result-display"   class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="monitor"></span></span><span class="outline-item-label">Result Display</span></a>              <a href="#!popup-size"       class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="popup-size"></span></span><span class="outline-item-label">Position & Size</span></a>              <a href="#!window"           class="button outline-item advanced-only"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="window"></span></span><span class="outline-item-label">Window</span></a>              <a href="#!audio"            class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="speaker"></span></span><span class="outline-item-label">Audio</span></a> @@ -112,6 +113,52 @@          </div></div>      </div> +        <!-- General --> +        <div class="heading-container"> +            <div class="heading-container-icon"><span class="icon" data-icon="cog"></span></div> +            <div class="heading-container-left"><h2 id="general"><a href="#!general">General</a></h2></div> +        </div> +        <div class="settings-group"> +            <div class="settings-item"><div class="settings-item-inner"> +                <div class="settings-item-left"> +                    <div class="settings-item-label">Enable Yomitan</div> +                </div> +                <div class="settings-item-right"> +                    <label class="toggle"><input type="checkbox" data-setting="general.enable"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +                </div> +            </div></div> +            <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +                <div class="settings-item-left"> +                    <div class="settings-item-label"> +                        Language +                    </div> +                    <div class="settings-item-description"> +                        Language of the text that is being looked up. +                    </div> +                </div> +                <div class="settings-item-right"> +                    <select id="language-select" data-setting="general.language"></select> +                </div> +            </div></div> +            <div class="settings-item"><div class="settings-item-inner"> +                <div class="settings-item-left"> +                    <div class="settings-item-label">Show the <a href="/welcome.html" target="_blank" rel="noopener">welcome guide</a> on browser startup</div> +                </div> +                <div class="settings-item-right"> +                    <label class="toggle"><input type="checkbox" data-setting="general.showGuide"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +                </div> +            </div></div> +            <div class="settings-item advanced-only"><div class="settings-item-inner settings-item-inner-wrappable"> +                <div class="settings-item-left"> +                    <div class="settings-item-label">Maximum number of results</div> +                    <div class="settings-item-description">Adjust the maximum number of results shown for lookups.</div> +                </div> +                <div class="settings-item-right"> +                    <input type="number" min="1" data-setting="general.maxResults"> +                </div> +            </div></div> +        </div> +      <!-- Dictionaries -->      <div class="heading-container">          <div class="heading-container-icon"><span class="icon" data-icon="book"></span></div> @@ -159,153 +206,6 @@              </div>          </div>          <div class="settings-item"> -            <div class="settings-item-inner"> -                <div class="settings-item-left"> -                    <div class="settings-item-label">Persistent storage</div> -                    <div class="settings-item-description"> -                        Enable to help prevent the browser from unexpectedly clearing the database. -                        <a tabindex="0" class="more-toggle more-only" data-parent-distance="4">More…</a> -                    </div> -                </div> -                <div class="settings-item-right"> -                    <label class="toggle"><input type="checkbox" id="storage-persistent-checkbox"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> -                </div> -            </div> -            <div class="settings-item-children more" hidden> -                <p> -                    Web browsers will sometimes clear stored data if the device is running low on storage space. -                    This can result in the imported dictionaries being deleted unexpectedly, causing Yomitan to stop functioning. -                    Enabling persistent storage tells the browser that the data should not be deleted in those circumstances. -                </p> -                <p data-show-for-browser="firefox firefox-mobile" class="storage-use-invalid" hidden> -                    On Firefox and Firefox for Android, the storage information feature may be hidden behind a browser flag. - -                    To enable this flag, open <a href="about:config" target="_blank" rel="noopener">about:config</a> and search for -                    <strong>dom.storageManager.enabled</strong>. - -                    Setting its value to <strong>true</strong> should allow storage information to be calculated. -                </p> -                <p data-show-for-browser="firefox-mobile"> -                    It may not be possible to enable Persistent Storage on Firefox for Android. -                </p> -                <p data-show-for-browser="chrome edge"> -                    Chromium-based browsers should not need to enable this setting since the Yomitan extension has -                    the <code>unlimitedStorage</code> permission, which should prevent data deletion.<sup><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=680392#c15" target="_blank" rel="noopener">[1]</a></sup> -                </p> -                <p> -                    <a tabindex="0" class="more-toggle" data-parent-distance="3">Less…</a> -                </p> -            </div> -        </div> -    </div> - -    <!-- General --> -    <div class="heading-container"> -        <div class="heading-container-icon"><span class="icon" data-icon="cog"></span></div> -        <div class="heading-container-left"><h2 id="general"><a href="#!general">General</a></h2></div> -    </div> -    <div class="settings-group"> -        <div class="settings-item"><div class="settings-item-inner"> -            <div class="settings-item-left"> -                <div class="settings-item-label">Enable content scanning</div> -            </div> -            <div class="settings-item-right"> -                <label class="toggle"><input type="checkbox" data-setting="general.enable"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> -            </div> -        </div></div> -        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> -            <div class="settings-item-left"> -                <div class="settings-item-label"> -                    Language -                </div> -                <div class="settings-item-description"> -                    Language of the text that is being looked up. -                </div> -            </div> -            <div class="settings-item-right"> -                <select id="language-select" data-setting="general.language"></select> -            </div> -        </div></div> -        <div class="settings-item"><div class="settings-item-inner"> -            <div class="settings-item-left"> -                <div class="settings-item-label">Show the <a href="/welcome.html" target="_blank" rel="noopener">welcome guide</a> on browser startup</div> -            </div> -            <div class="settings-item-right"> -                <label class="toggle"><input type="checkbox" data-setting="general.showGuide"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> -            </div> -        </div></div> -        <div class="settings-item"> -            <div class="settings-item-inner settings-item-inner-wrappable"> -                <div class="settings-item-left"> -                    <div class="settings-item-label">Result grouping mode</div> -                    <div class="settings-item-description"> -                        Change how related results are grouped. -                        <a tabindex="0" class="more-toggle more-only" data-parent-distance="4">More…</a> -                    </div> -                </div> -                <div class="settings-item-right"> -                    <select data-setting="general.resultOutputMode" -                        data-transform='{ -                            "type": "setVisibility", -                            "selector": "#main-dictionary-container", -                            "condition": {"op": "===", "value": "merge"} -                        }' -                    > -                        <option value="split">No grouping</option> -                        <option value="group">Group term-reading pairs</option> -                        <option value="merge">Group related terms</option> -                    </select> -                </div> -            </div> -            <div class="settings-item-children more" hidden> -                <ul> -                    <li> -                        <strong>No grouping</strong> - -                        Every definition will be listed as a separate entry. -                    </li> -                    <li> -                        <strong>Group term-reading pairs</strong> - -                        Definitions for the same term with the same reading will be grouped together. -                    </li> -                    <li> -                        <p> -                            <strong>Group related terms</strong> - -                            Related terms that share the same definitions will be grouped together. -                        </p> -                        <p> -                            The <em>Primary dictionary</em> option should be assigned to a dictionary which contains related term information, -                            and configuring the <em>Secondary dictionaries</em> will allow definitions for the related terms to be -                            included from other dictionaries. -                        </p> -                        <p class="warning-text"> -                            Not all dictionaries are able to be selected as the <em>Primary dictionary</em>. -                        </p> -                    </li> -                </ul> -                <p> -                    <a tabindex="0" class="more-toggle" data-parent-distance="3">Less…</a> -                </p> -            </div> -            <div class="settings-item-children settings-item-children-group" id="main-dictionary-container" hidden> -                <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> -                    <div class="settings-item-left"> -                        <div class="settings-item-label">Primary dictionary</div> -                    </div> -                    <div class="settings-item-right"> -                        <select data-setting="general.mainDictionary"></select> -                    </div> -                </div></div> -                <div class="settings-item settings-item-button" data-modal-action="show,secondary-search-dictionaries"><div class="settings-item-inner"> -                    <div class="settings-item-left"> -                        <div class="settings-item-label">Secondary dictionaries…</div> -                    </div> -                    <div class="settings-item-right open-panel-button-container"> -                        <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> -                    </div> -                </div></div> -            </div> -        </div> -        <div class="settings-item advanced-only">              <div class="settings-item-inner settings-item-inner-wrappable">                  <div class="settings-item-left">                      <div class="settings-item-label">Frequency sorting dictionary</div> @@ -328,7 +228,7 @@                      <a tabindex="0" class="more-toggle" data-parent-distance="3">Less…</a>                  </p>              </div> -            <div class="settings-item-children settings-item-children-group" id="sort-frequency-dictionary-order-container" hidden> +            <div class="settings-item-children settings-item-children-group advanced-only" id="sort-frequency-dictionary-order-container" hidden>                  <div class="settings-item">                      <div class="settings-item-inner settings-item-inner-wrappable">                          <div class="settings-item-left"> @@ -372,15 +272,45 @@                  </div>              </div>          </div> -        <div class="settings-item advanced-only"><div class="settings-item-inner settings-item-inner-wrappable"> -            <div class="settings-item-left"> -                <div class="settings-item-label">Maximum number of results</div> -                <div class="settings-item-description">Adjust the maximum number of results shown for lookups.</div> +        <div class="settings-item"> +            <div class="settings-item-inner"> +                <div class="settings-item-left"> +                    <div class="settings-item-label">Persistent storage</div> +                    <div class="settings-item-description"> +                        Enable to help prevent the browser from unexpectedly clearing the database. +                        <a tabindex="0" class="more-toggle more-only" data-parent-distance="4">More…</a> +                    </div> +                </div> +                <div class="settings-item-right"> +                    <label class="toggle"><input type="checkbox" id="storage-persistent-checkbox"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +                </div>              </div> -            <div class="settings-item-right"> -                <input type="number" min="1" data-setting="general.maxResults"> +            <div class="settings-item-children more" hidden> +                <p> +                    Web browsers will sometimes clear stored data if the device is running low on storage space. +                    This can result in the imported dictionaries being deleted unexpectedly, causing Yomitan to stop functioning. +                    Enabling persistent storage tells the browser that the data should not be deleted in those circumstances. +                </p> +                <p data-show-for-browser="firefox firefox-mobile" class="storage-use-invalid" hidden> +                    On Firefox and Firefox for Android, the storage information feature may be hidden behind a browser flag. + +                    To enable this flag, open <a href="about:config" target="_blank" rel="noopener">about:config</a> and search for +                    <strong>dom.storageManager.enabled</strong>. + +                    Setting its value to <strong>true</strong> should allow storage information to be calculated. +                </p> +                <p data-show-for-browser="firefox-mobile"> +                    It may not be possible to enable Persistent Storage on Firefox for Android. +                </p> +                <p data-show-for-browser="chrome edge"> +                    Chromium-based browsers should not need to enable this setting since the Yomitan extension has +                    the <code>unlimitedStorage</code> permission, which should prevent data deletion.<sup><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=680392#c15" target="_blank" rel="noopener">[1]</a></sup> +                </p> +                <p> +                    <a tabindex="0" class="more-toggle" data-parent-distance="3">Less…</a> +                </p>              </div> -        </div></div> +        </div>      </div>      <!-- Scanning --> @@ -434,61 +364,7 @@                  <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button>              </div>          </div></div> -        <div class="settings-item"> -            <div class="settings-item-inner"> -                <div class="settings-item-left"> -                    <div class="settings-item-label">Auto-hide search popup</div> -                    <div class="settings-item-description">When no definitions are found after scanning text, the popup will be hidden.</div> -                </div> -                <div class="settings-item-right"> -                    <label class="toggle"><input type="checkbox" data-setting="scanning.autoHideResults" -                        data-transform='{ -                            "type": "setVisibility", -                            "selector": "#auto-hide-search-popup-options", -                            "condition": {"op": "===", "value": true} -                        }' -                    ><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> -                </div> -            </div> -            <div class="settings-item-children settings-item-children-group" id="auto-hide-search-popup-options" hidden> -                <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> -                    <div class="settings-item-left"> -                        <div class="settings-item-label">Delay <span class="light">(in milliseconds)</span></div> -                    </div> -                    <div class="settings-item-right"> -                        <input type="number" data-setting="scanning.hideDelay" min="0"> -                    </div> -                </div></div> -            </div> -        </div> -        <div class="settings-item"> -            <div class="settings-item-inner"> -                <div class="settings-item-left"> -                    <div class="settings-item-label">Hide popup on cursor exit</div> -                    <div class="settings-item-description">When the cursor exits the popup, the popup will be hidden.</div> -                </div> -                <div class="settings-item-right"> -                    <label class="toggle"><input type="checkbox" data-setting="scanning.hidePopupOnCursorExit" -                        data-transform='{ -                            "type": "setVisibility", -                            "selector": "#hide-popup-on-cursor-exit-options", -                            "condition": {"op": "===", "value": true} -                        }' -                    ><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> -                </div> -            </div> -            <div class="settings-item-children settings-item-children-group" id="hide-popup-on-cursor-exit-options" hidden> -                <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> -                    <div class="settings-item-left"> -                        <div class="settings-item-label">Delay <span class="light">(in milliseconds)</span></div> -                    </div> -                    <div class="settings-item-right"> -                        <input type="number" data-setting="scanning.hidePopupOnCursorExitDelay" min="0"> -                    </div> -                </div></div> -            </div> -        </div> -        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +        <div class="settings-item advanced-only"><div class="settings-item-inner settings-item-inner-wrappable">              <div class="settings-item-left">                  <div class="settings-item-label">Scan delay <span class="light">(in milliseconds)</span></div>                  <div class="settings-item-description">Change the delay before scanning occurs when no modifier key is required.</div> @@ -589,6 +465,9 @@              <div class="settings-item-left">                  <div class="settings-item-label">Text scan length</div>                  <div class="settings-item-description">Change how many characters are read when scanning for terms.</div> +                <div class="warning-text margin-above"> +                    <strong>Setting this value too high (100+) may impact performance.</strong> +                </div>              </div>              <div class="settings-item-right">                  <input type="number" data-setting="scanning.length" min="1" step="1"> @@ -640,10 +519,10 @@          </div></div>      </div> -    <!-- Popup --> +    <!-- Popup Behavior -->      <div class="heading-container">          <div class="heading-container-icon"><span class="icon" data-icon="popup"></span></div> -        <div class="heading-container-left"><h2 id="popup"><a href="#!popup">Popup</a></h2></div> +        <div class="heading-container-left"><h2 id="popup"><a href="#!popup">Popup Behavior</a></h2></div>      </div>      <div class="settings-group">          <div class="settings-item"><div class="settings-item-inner"> @@ -685,6 +564,60 @@                  </div></div>              </div>          </div> +        <div class="settings-item"> +            <div class="settings-item-inner"> +                <div class="settings-item-left"> +                    <div class="settings-item-label">Auto-hide search popup</div> +                    <div class="settings-item-description">When an existing popup is present, upon scanning again, hide the existing popup even if no definitions are found when scanning again.</div> +                </div> +                <div class="settings-item-right"> +                    <label class="toggle"><input type="checkbox" data-setting="scanning.autoHideResults" +                        data-transform='{ +                            "type": "setVisibility", +                            "selector": "#auto-hide-search-popup-options", +                            "condition": {"op": "===", "value": true} +                        }' +                    ><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +                </div> +            </div> +            <div class="settings-item-children settings-item-children-group" id="auto-hide-search-popup-options" hidden> +                <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +                    <div class="settings-item-left"> +                        <div class="settings-item-label">Delay <span class="light">(in milliseconds)</span></div> +                    </div> +                    <div class="settings-item-right"> +                        <input type="number" data-setting="scanning.hideDelay" min="0"> +                    </div> +                </div></div> +            </div> +        </div> +        <div class="settings-item"> +            <div class="settings-item-inner"> +                <div class="settings-item-left"> +                    <div class="settings-item-label">Hide popup on cursor exit</div> +                    <div class="settings-item-description">When the cursor exits the popup, the popup will be hidden.</div> +                </div> +                <div class="settings-item-right"> +                    <label class="toggle"><input type="checkbox" data-setting="scanning.hidePopupOnCursorExit" +                        data-transform='{ +                            "type": "setVisibility", +                            "selector": "#hide-popup-on-cursor-exit-options", +                            "condition": {"op": "===", "value": true} +                        }' +                    ><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +                </div> +            </div> +            <div class="settings-item-children settings-item-children-group" id="hide-popup-on-cursor-exit-options" hidden> +                <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +                    <div class="settings-item-left"> +                        <div class="settings-item-label">Delay <span class="light">(in milliseconds)</span></div> +                    </div> +                    <div class="settings-item-right"> +                        <input type="number" data-setting="scanning.hidePopupOnCursorExitDelay" min="0"> +                    </div> +                </div></div> +            </div> +        </div>          <div class="settings-item advanced-only"><div class="settings-item-inner">              <div class="settings-item-left">                  <div class="settings-item-label">Search terms when clicking text from the results list</div> @@ -723,10 +656,10 @@          </div>      </div> -    <!-- Popup Appearance --> +    <!-- Appearance -->      <div class="heading-container">          <div class="heading-container-icon"><span class="icon" data-icon="palette"></span></div> -        <div class="heading-container-left"><h2 id="popup-appearance"><a href="#!popup-appearance">Popup Appearance</a></h2></div> +        <div class="heading-container-left"><h2 id="appearance"><a href="#!appearance">Appearance</a></h2></div>      </div>      <div class="settings-group">          <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> @@ -855,6 +788,21 @@                  </select>              </div>          </div></div> +        <div class="settings-item advanced-only"><div class="settings-item-inner settings-item-inner-wrappable"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Reading mode</div> +                <div class="settings-item-description">Change what type of furigana is displayed for parsed text.</div> +            </div> +            <div class="settings-item-right"> +                <select data-setting="parsing.readingMode" lang="ja"> +                    <option value="none">None</option> +                    <option value="hiragana">ひらがな</option> +                    <option value="katakana">カタカナ</option> +                    <option value="romaji">Romaji</option> +                    <option value="dictionary-reading">Dictionary reading</option> +                </select> +            </div> +        </div></div>          <div class="settings-item advanced-only"><div class="settings-item-inner">              <div class="settings-item-left">                  <div class="settings-item-label">Frequency display style</div> @@ -890,7 +838,7 @@                  </div>              </div>          </div> -        <div class="settings-item advanced-only"> +        <div class="settings-item">              <div class="settings-item-inner settings-item-inner-wrappable">                  <div class="settings-item-left">                      <div class="settings-item-label"> @@ -962,7 +910,7 @@                  <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button>              </div>          </div></div> -        <div class="settings-item settings-item-button" data-modal-action="show,custom-css"><div class="settings-item-inner"> +        <div class="settings-item settings-item-button advanced-only" data-modal-action="show,custom-css"><div class="settings-item-inner">              <div class="settings-item-left">                  <div class="settings-item-label">Configure custom CSS…</div>              </div> @@ -972,6 +920,85 @@          </div></div>      </div> +    <!-- Result Display --> +    <div class="heading-container"> +        <div class="heading-container-icon"><span class="icon" data-icon="monitor"></span></div> +        <div class="heading-container-left"><h2 id="result-display"><a href="#!result-display">Result Display</a></h2></div> +    </div> +    <div class="settings-group"> +        <div class="settings-item"> +            <div class="settings-item-inner settings-item-inner-wrappable"> +                <div class="settings-item-left"> +                    <div class="settings-item-label">Result grouping mode</div> +                    <div class="settings-item-description"> +                        Change how related results are grouped. +                        <a tabindex="0" class="more-toggle more-only" data-parent-distance="4">More…</a> +                    </div> +                </div> +                <div class="settings-item-right"> +                    <select data-setting="general.resultOutputMode" +                        data-transform='{ +                            "type": "setVisibility", +                            "selector": "#main-dictionary-container", +                            "condition": {"op": "===", "value": "merge"} +                        }' +                    > +                        <option value="split">No grouping</option> +                        <option value="group">Group term-reading pairs</option> +                        <option value="merge">Group related terms</option> +                    </select> +                </div> +            </div> +            <div class="settings-item-children more" hidden> +                <ul> +                    <li> +                        <strong>No grouping</strong> - +                        Every definition will be listed as a separate entry. +                    </li> +                    <li> +                        <strong>Group term-reading pairs</strong> - +                        Definitions for the same term with the same reading will be grouped together. +                    </li> +                    <li> +                        <p> +                            <strong>Group related terms</strong> - +                            Related terms that share the same definitions will be grouped together. +                        </p> +                        <p> +                            The <em>Primary dictionary</em> option should be assigned to a dictionary which contains related term information, +                            and configuring the <em>Secondary dictionaries</em> will allow definitions for the related terms to be +                            included from other dictionaries. +                        </p> +                        <p class="warning-text"> +                            Not all dictionaries are able to be selected as the <em>Primary dictionary</em>. +                        </p> +                    </li> +                </ul> +                <p> +                    <a tabindex="0" class="more-toggle" data-parent-distance="3">Less…</a> +                </p> +            </div> +            <div class="settings-item-children settings-item-children-group" id="main-dictionary-container" hidden> +                <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +                    <div class="settings-item-left"> +                        <div class="settings-item-label">Primary dictionary</div> +                    </div> +                    <div class="settings-item-right"> +                        <select data-setting="general.mainDictionary"></select> +                    </div> +                </div></div> +                <div class="settings-item settings-item-button" data-modal-action="show,secondary-search-dictionaries"><div class="settings-item-inner"> +                    <div class="settings-item-left"> +                        <div class="settings-item-label">Secondary dictionaries…</div> +                    </div> +                    <div class="settings-item-right open-panel-button-container"> +                        <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> +                    </div> +                </div></div> +            </div> +        </div> +    </div> +      <!-- Popup Position & Size -->      <div class="heading-container">          <div class="heading-container-icon"><span class="icon" data-icon="popup-size"></span></div> @@ -1368,7 +1395,7 @@          </div>      </div>      <div class="settings-group"> -        <div class="settings-item"> +        <div class="settings-item advanced-only">              <div class="settings-item-inner">                  <div class="settings-item-left">                      <div class="settings-item-label">Parse sentences using Yomitan's internal parser</div> @@ -1435,21 +1462,6 @@                  <label class="toggle"><input type="checkbox" data-setting="parsing.termSpacing"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>              </div>          </div></div> -        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> -            <div class="settings-item-left"> -                <div class="settings-item-label">Reading mode</div> -                <div class="settings-item-description">Change what type of furigana is displayed for parsed text.</div> -            </div> -            <div class="settings-item-right"> -                <select data-setting="parsing.readingMode" lang="ja"> -                    <option value="none">None</option> -                    <option value="hiragana">ひらがな</option> -                    <option value="katakana">カタカナ</option> -                    <option value="romaji">Romaji</option> -                    <option value="dictionary-reading">Dictionary reading</option> -                </select> -            </div> -        </div></div>          <div class="settings-item advanced-only"><div class="settings-item-inner settings-item-inner-wrappable">              <div class="settings-item-left">                  <div class="settings-item-label">Sentence scanning extent</div> @@ -1895,7 +1907,7 @@                  <label class="toggle"><input type="checkbox" class="permissions-toggle" data-permissions-setting="clipboard.enableSearchPageMonitor" data-required-permissions="clipboardRead"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>              </div>          </div></div> -        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable"> +        <div class="settings-item advanced-only"><div class="settings-item-inner settings-item-inner-wrappable">              <div class="settings-item-left">                  <div class="settings-item-label">Maximum clipboard text search length</div>                  <div class="settings-item-description">Limit the number of characters used when searching clipboard text.</div> @@ -2039,20 +2051,6 @@                  </div>              </div>          </div></div> -        <div class="settings-item"><div class="settings-item-inner"> -            <div class="settings-item-left"> -                <div class="settings-item-progress-report" id="db-ops-progress-report"> -                    Placeholder text. -                </div> -            </div> -        </div></div> -        <div class="settings-item"><div class="settings-item-inner"> -            <div class="settings-item-left"> -                <div class="settings-item-error-report" id="db-ops-error-report"> -                    Placeholder text. -                </div> -            </div> -        </div></div>      </div>      <!-- Accessibility --> diff --git a/ext/welcome.html b/ext/welcome.html index d15686a1..f2192686 100644 --- a/ext/welcome.html +++ b/ext/welcome.html @@ -26,6 +26,22 @@      <h1>Welcome to Yomitan!</h1> +    <h2><strong>Recommended Permissions (Important)</strong></h2> +    <div class="settings-group"> +        <div class="settings-item"><div class="settings-item-inner"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Enable recommended permissions</div> +                <div class="settings-item-description">This will allow Yomitan to scan text from most sites. Further configuration is available on the <a href="/permissions.html" rel="noopener">Permissions page</a>.</div> +                <div class="danger-text margin-above" id="permissions-disabled" hidden><strong>Yomitan features will be limited if the recommended permissions are not enabled.</strong></div> +                <div class="success-text margin-above" id="permissions-enabled" hidden><strong>All Yomitan features are available.</strong></div> +                <div id="recommended-permissions-error" class="margin-above danger-text" hidden></div> +            </div> +            <div class="settings-item-right"> +                <label class="toggle"><input type="checkbox" id="recommended-permissions-toggle" data-origin="<all_urls>"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +            </div> +        </div></div> +    </div> +      <!-- Notifications -->      <div class="settings-group settings-group-top-margin warn-custom-templates-notification">        <div class="settings-item"> @@ -41,103 +57,37 @@      <!-- Content -->      <h2>Here are some basics to get started</h2>      <div class="settings-group"> -        <div class="settings-item"> -            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                Clicking the <img src="/images/yomitan-icon.svg" class="inline-icon" alt=""> <em>Yomitan</em> button in the browser bar will open the quick-actions popup. -            </div></div></div> -            <div class="settings-item-children settings-item-children-group"> -                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                    The <img src="/images/cog.svg" class="inline-icon" alt=""> <em>cog</em> button will open the <a href="/settings.html" target="_blank" rel="noopener">Settings</a> page. -                </div></div></div></div> -                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                    The <img src="/images/magnifying-glass.svg" class="inline-icon" alt=""> <em>magnifying glass</em> button will open the <a href="/search.html" target="_blank" rel="noopener">Search</a> page, -                    enabling text and terms to be looked up using the installed dictionaries. -                    This can even be used in offline mode! -                </div></div></div></div> -                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                    The <img src="/images/question-mark-circle.svg" class="inline-icon" alt=""> <em>question mark</em> button will open the <a href="/info.html" target="_blank" rel="noopener">Information</a> page, -                    which has some helpful information and links about Yomitan. -                </div></div></div></div> -            </div> -        </div> -        <div class="settings-item"> -            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                Yomitan requires one or more dictionaries to be installed in order to look up terms, kanji, and other information. -                Several downloadable dictionaries can be found on the <a href="https://github.com/themoeway/yomitan/blob/master/docs/dictionaries.md#dictionaries" target="_blank" rel="noopener noreferrer">Yomitan homepage</a>. -                Dictionaries can be configured using the button below, -                or later from the <a href="/settings.html" rel="noopener">Settings</a> page. -            </div></div></div> -            <div class="settings-item-children settings-item-children-group"> -                <div class="settings-item settings-item-button" data-modal-action="show,dictionaries"><div class="settings-item-inner"> -                    <div class="settings-item-left"> -                        <div class="settings-item-label">Install or remove dictionaries…</div> -                    </div> -                    <div class="settings-item-right open-panel-button-container"> -                        <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button> -                    </div> -                </div></div> +        <a href="/quick-start-guide.html" rel="noopener" class="settings-item settings-item-button"><div class="settings-item-inner"> +            <div class="settings-item-left"> +                <div class="settings-item-label">Yomitan Quick Start Guide</div>              </div> -        </div> -        <div class="settings-item"> -            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                You can also import an exported collection of dictionaries from the <a href="/settings.html#!backup">Backup section of the Settings</a> page. - -                <br><br> - -                If you are migrating from Yomichan, you may be interested in importing your data into Yomitan. -                Please follow instructions from <a href="https://github.com/themoeway/yomitan/blob/master/docs/yomichan-migration.md#migrating-from-yomichan" target="_blank" rel="noopener noreferrer">Yomitan's README</a> for that. - -                <br><br> - -                If you are using or planning to use custom templates for Anki note creation, note that <a href="https://github.com/themoeway/yomitan/blob/master/docs/yomichan-migration.md#custom-templates" target="_blank" rel="noopener noreferrer">some syntax has changed from Yomichan and Yomibaba.</a> -                Please ensure that your custom templates are using the updated syntax. -            </div></div></div> -        </div> -        <div class="settings-item"> -            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                After dictionaries have been installed, webpage text can be scanned by moving the cursor while holding a modifier key. -                The default key is <kbd>Shift</kbd>, which can be disabled or configured below. -            </div></div></div> -            <div class="settings-item-children settings-item-children-group"> -                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                    Clicking the <img src="/images/play-audio.svg" class="inline-icon" alt=""> <em>speaker</em> button of an entry in the search results -                    will play an audio clip of a term's pronunciation using an online dictionary, if available. -                </div></div></div></div> -                <div class="settings-item"><div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                    Clicking on a kanji character in a term's definition will show additional information about that character. -                    <span class="light">(Requires a kanji dictionary to be installed.)</span> -                </div></div></div></div> +            <div class="settings-item-right open-panel-button-container"> +                <button type="button" class="icon-button"><span class="icon-button-inner"><span class="icon" data-icon="material-right-arrow"></span></span></button>              </div> -        </div> -        <div class="settings-item"> -            <div class="settings-item-inner"><div class="settings-item-left"><div class="settings-item-label"> -                This startup notification can be turned off using the options below, or later from the <a href="/settings.html" rel="noopener">Settings</a> page. -            </div></div></div> -        </div> +        </div></a>      </div> -    <h2>Recommended Permissions (Important)</h2> +    <h2>Basic customization</h2>      <div class="settings-group">          <div class="settings-item"><div class="settings-item-inner">              <div class="settings-item-left"> -                <div class="settings-item-label">Enable recommended permissions</div> -                <div class="settings-item-description">This will allow Yomitan to scan text from most sites. Further configuration is available on the <a href="/permissions.html" rel="noopener">Permissions page</a>.</div> +                <div class="settings-item-label">Show this welcome guide on browser startup</div>              </div>              <div class="settings-item-right"> -                <label class="toggle"><input type="checkbox" class="recommended-permissions-toggle" data-origin="<all_urls>"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +                <label class="toggle"><input type="checkbox" data-setting="general.showGuide"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>              </div> -            <div id="recommended-permissions-error" class="margin-above danger-text" hidden></div>          </div></div> -    </div> - -    <h2>Basic customization</h2> -    <div class="settings-group"> -        <div class="settings-item"><div class="settings-item-inner"> +        <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable">              <div class="settings-item-left"> -                <div class="settings-item-label">Show this welcome guide on browser startup</div> +                <div class="settings-item-label"> +                    Language +                </div> +                <div class="settings-item-description"> +                    Language of the text that is being looked up. +                </div>              </div>              <div class="settings-item-right"> -                <label class="toggle"><input type="checkbox" data-setting="general.showGuide"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> +                <select id="language-select" data-setting="general.language"></select>              </div>          </div></div>          <div class="settings-item"> @@ -160,42 +110,6 @@                  <label class="toggle"><input type="checkbox" id="middle-mouse-button-scan"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>              </div>          </div></div> -        <div class="settings-item"> -            <div class="settings-item-inner"> -                <div class="settings-item-left"> -                    <div class="settings-item-label">Auto-hide search popup</div> -                    <div class="settings-item-description">When no definitions are found after scanning text, the popup will be hidden.</div> -                </div> -                <div class="settings-item-right"> -                    <label class="toggle"><input type="checkbox" data-setting="scanning.autoHideResults" -                        data-transform='{ -                            "type": "setVisibility", -                            "selector": "#auto-hide-search-popup-options", -                            "condition": {"op": "===", "value": true} -                        }' -                    ><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> -                </div> -            </div> -            <div class="settings-item-children settings-item-children-group" id="auto-hide-search-popup-options" hidden> -                <div class="settings-item"><div class="settings-item-inner"> -                    <div class="settings-item-left"> -                        <div class="settings-item-label">Delay <span class="light">(in milliseconds)</span></div> -                    </div> -                    <div class="settings-item-right"> -                        <input type="number" data-setting="scanning.hideDelay" min="0"> -                    </div> -                </div></div> -            </div> -        </div> -        <div class="settings-item"><div class="settings-item-inner"> -            <div class="settings-item-left"> -                <div class="settings-item-label">Scan delay <span class="light">(in milliseconds)</span></div> -                <div class="settings-item-description">Change the delay before scanning occurs when no modifier key is required.</div> -            </div> -            <div class="settings-item-right"> -                <input type="number" data-setting="scanning.delay" min="0"> -            </div> -        </div></div>          <div class="settings-item"><div class="settings-item-inner settings-item-inner-wrappable">              <div class="settings-item-left">                  <div class="settings-item-label">Theme</div> |