diff options
-rw-r--r-- | ext/bg/css/settings2.css | 14 | ||||
-rw-r--r-- | ext/bg/guide.html | 40 | ||||
-rw-r--r-- | ext/bg/js/backend.js | 2 | ||||
-rw-r--r-- | ext/bg/js/settings/dictionary-controller.js | 35 | ||||
-rw-r--r-- | ext/bg/js/settings/dictionary-import-controller.js | 7 | ||||
-rw-r--r-- | ext/bg/js/settings2/settings-display-controller.js | 6 | ||||
-rw-r--r-- | ext/bg/js/welcome-main.js | 84 | ||||
-rw-r--r-- | ext/bg/settings2.html | 2 | ||||
-rw-r--r-- | ext/bg/welcome.html | 372 |
9 files changed, 500 insertions, 62 deletions
diff --git a/ext/bg/css/settings2.css b/ext/bg/css/settings2.css index 9b5bea81..e15fa080 100644 --- a/ext/bg/css/settings2.css +++ b/ext/bg/css/settings2.css @@ -46,9 +46,10 @@ --settings-group-wrap: nowrap; --show-preview-label-height: 40px; - --font-size-default: 14px; + --font-size-default-no-units: 14; + --font-size-default: calc(1px * var(--font-size-default-no-units)); --font-size-small: 12px; - --line-height-default: calc(20 / 14); + --line-height-default: calc(20 / var(--font-size-default-no-units)); --outline-item-height: 40px; --outline-item-icon-size: 32px; --input-width: 100px; @@ -586,9 +587,16 @@ h3 { .settings-group.settings-group-top-margin { margin-top: 1.0125em; } +.settings-item:not([hidden]) { + display: block; +} .settings-item-button { cursor: pointer; } +a.settings-item-button { + color: var(--text-color-default); + text-decoration: none; +} .settings-item-outer { display: block; width: 100%; @@ -2335,7 +2343,7 @@ code.anki-field-marker { margin: 0; padding: 0; width: 100%; - height: calc(0.425em * 4 + 1em * (20 / 14) * 3); + height: calc(0.425em * 4 + 1em * var(--line-height-default) * 3); } diff --git a/ext/bg/guide.html b/ext/bg/guide.html deleted file mode 100644 index d75a9931..00000000 --- a/ext/bg/guide.html +++ /dev/null @@ -1,40 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width,initial-scale=1" /> - <title>Welcome to Yomichan!</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"> - </head> - <body> - <div class="container"> - <div class="page-header"> - <h1>Yomichan Usage Guide</h1> - </div> - - <p> - Read the steps below to get up and running with Yomichan. For complete documentation, - visit the <a href="https://foosoft.net/projects/yomichan/" target="_blank" rel="noopener">official homepage</a>. - </p> - - <ol> - <li>Click on the <img src="/mixed/img/yomichan-icon.svg" alt> icon in the browser toolbar to open the Yomichan actions dialog.</li> - <li>Click on the <em>cog</em> icon in the middle to open the options page.</li> - <li>Import the dictionaries you wish to use for term and Kanji searches.</li> - <li>Hold down <kbd>Shift</kbd> key or the middle mouse button as you move your mouse over text to display definitions.</li> - <li>Click on the <img src="/mixed/img/play-audio.svg" alt> icon to hear the term pronounced by a native speaker.</li> - <li>Click on individual Kanji in the term definition results to view additional information about those characters.</li> - </ol> - - <p>This startup notification can be turned off on the Yomichan options page.</p> - </div> - </body> -</html> diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index b2ea3cd6..3229e278 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -206,7 +206,7 @@ class Backend { const options = this.getOptions({current: true}); if (options.general.showGuide) { - chrome.tabs.create({url: chrome.runtime.getURL('/bg/guide.html')}); + chrome.tabs.create({url: chrome.runtime.getURL('/bg/welcome.html')}); } this._clipboardMonitor.on('change', this._onClipboardTextChange.bind(this)); diff --git a/ext/bg/js/settings/dictionary-controller.js b/ext/bg/js/settings/dictionary-controller.js index ba28ba1c..2592e6a2 100644 --- a/ext/bg/js/settings/dictionary-controller.js +++ b/ext/bg/js/settings/dictionary-controller.js @@ -58,22 +58,29 @@ class DictionaryEntry { const versionNode = node.querySelector('.dictionary-version'); const wildcardSupportedCheckbox = node.querySelector('.dictionary-prefix-wildcard-searches-supported'); - const hasDetails = this._setupDetails(detailsTable); + const hasDetails = (detailsTable !== null && this._setupDetails(detailsTable)); this._hasDetails = hasDetails; titleNode.textContent = title; versionNode.textContent = `rev.${revision}`; - wildcardSupportedCheckbox.checked = !!prefixWildcardsSupported; - - outdatedContainer.hidden = (version >= 3); - if (detailsToggleLink !== null) { detailsToggleLink.hidden = !hasDetails; } - - enabledCheckbox.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'enabled']); - priorityInput.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'priority']); + if (wildcardSupportedCheckbox !== null) { + wildcardSupportedCheckbox.checked = !!prefixWildcardsSupported; + } + if (outdatedContainer !== null) { + outdatedContainer.hidden = (version >= 3); + } + if (detailsToggleLink !== null) { + detailsToggleLink.hidden = !hasDetails; + } + if (enabledCheckbox !== null) { + enabledCheckbox.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'enabled']); + } + if (priorityInput !== null) { + priorityInput.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'priority']); + } if (allowSecondarySearchesCheckbox !== null) { allowSecondarySearchesCheckbox.dataset.setting = ObjectPropertyAccessor.getPathString(['dictionaries', title, 'allowSecondarySearches']); } - if (deleteButton !== null) { this._eventListeners.addEventListener(deleteButton, 'click', this._onDeleteButtonClicked.bind(this), false); } @@ -84,7 +91,9 @@ class DictionaryEntry { if (detailsToggleLink !== null && this._detailsContainer !== null) { this._eventListeners.addEventListener(detailsToggleLink, 'click', this._onDetailsToggleLinkClicked.bind(this), false); } - this._eventListeners.addEventListener(priorityInput, 'settingChanged', this._onPriorityChanged.bind(this), false); + if (priorityInput !== null) { + this._eventListeners.addEventListener(priorityInput, 'settingChanged', this._onPriorityChanged.bind(this), false); + } } cleanup() { @@ -213,7 +222,9 @@ class DictionaryController { yomichan.on('databaseUpdated', this._onDatabaseUpdated.bind(this)); document.querySelector('#dictionary-confirm-delete-button').addEventListener('click', this._onDictionaryConfirmDelete.bind(this), false); - this._checkIntegrityButton.addEventListener('click', this._onCheckIntegrityButtonClick.bind(this), false); + if (this._checkIntegrityButton !== null) { + this._checkIntegrityButton.addEventListener('click', this._onCheckIntegrityButtonClick.bind(this), false); + } await this._onDatabaseUpdated(); } @@ -433,8 +444,8 @@ class DictionaryController { for (const progress of progressContainers) { progress.hidden = true; } if (statusFooter !== null) { statusFooter.setTaskActive(progressSelector, false); } this._setButtonsEnabled(true); - storageController.updateStats(); this._isDeleting = false; + if (storageController !== null) { storageController.updateStats(); } } } diff --git a/ext/bg/js/settings/dictionary-import-controller.js b/ext/bg/js/settings/dictionary-import-controller.js index 15632d62..4945d54c 100644 --- a/ext/bg/js/settings/dictionary-import-controller.js +++ b/ext/bg/js/settings/dictionary-import-controller.js @@ -93,7 +93,7 @@ class DictionaryImportController { if (this._modifying) { return; } const purgeNotification = this._purgeNotification; - + const storageController = this._storageController; const prevention = this._preventPageExit(); try { @@ -114,8 +114,8 @@ class DictionaryImportController { prevention.end(); if (purgeNotification !== null) { purgeNotification.hidden = true; } this._setSpinnerVisible(false); - this._storageController.updateStats(); this._setModifying(false); + if (storageController !== null) { storageController.updateStats(); } } } @@ -157,7 +157,7 @@ class DictionaryImportController { const statusString = `${percent.toFixed(0)}%`; for (const progressBar of progressBars) { progressBar.style.width = cssString; } for (const label of statusLabels) { label.textContent = statusString; } - storageController.updateStats(); + if (storageController !== null) { storageController.updateStats(); } }; const fileCount = files.length; @@ -187,6 +187,7 @@ class DictionaryImportController { } this._setSpinnerVisible(false); this._setModifying(false); + if (storageController !== null) { storageController.updateStats(); } } } diff --git a/ext/bg/js/settings2/settings-display-controller.js b/ext/bg/js/settings2/settings-display-controller.js index 2be7bf92..d0fcffd9 100644 --- a/ext/bg/js/settings2/settings-display-controller.js +++ b/ext/bg/js/settings2/settings-display-controller.js @@ -73,8 +73,10 @@ class SettingsDisplayController { }); menuSelectorObserver.observe(document.documentElement, false); - this._contentNode.addEventListener('scroll', this._onScroll.bind(this), {passive: true}); - this._topLink.addEventListener('click', this._onTopLinkClick.bind(this), false); + if (this._topLink !== null) { + this._contentNode.addEventListener('scroll', this._onScroll.bind(this), {passive: true}); + this._topLink.addEventListener('click', this._onTopLinkClick.bind(this), false); + } window.addEventListener('keydown', this._onKeyDown.bind(this), false); window.addEventListener('popstate', this._onPopState.bind(this), false); diff --git a/ext/bg/js/welcome-main.js b/ext/bg/js/welcome-main.js new file mode 100644 index 00000000..504bd88b --- /dev/null +++ b/ext/bg/js/welcome-main.js @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2019-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/>. + */ + +/* global + * DictionaryController + * DictionaryImportController + * GenericSettingController + * ModalController + * ScanInputsSimpleController + * SettingsController + * SettingsDisplayController + * StatusFooter + * api + */ + +async function setupEnvironmentInfo() { + const {browser, platform} = await api.getEnvironmentInfo(); + document.documentElement.dataset.browser = browser; + document.documentElement.dataset.os = platform.os; +} + +async function setupGenericSettingsController(genericSettingController) { + await genericSettingController.prepare(); + await genericSettingController.refresh(); +} + +(async () => { + try { + document.querySelector('#content-scroll-focus').focus(); + + const statusFooter = new StatusFooter(document.querySelector('.status-footer-container')); + statusFooter.prepare(); + + api.forwardLogsToBackend(); + await yomichan.prepare(); + + setupEnvironmentInfo(); + + const optionsFull = await api.optionsGetFull(); + + const preparePromises = []; + + const modalController = new ModalController(); + modalController.prepare(); + + const settingsController = new SettingsController(optionsFull.profileCurrent); + settingsController.prepare(); + + const dictionaryController = new DictionaryController(settingsController, modalController, null, statusFooter); + dictionaryController.prepare(); + + const dictionaryImportController = new DictionaryImportController(settingsController, modalController, null, statusFooter); + dictionaryImportController.prepare(); + + const genericSettingController = new GenericSettingController(settingsController); + preparePromises.push(setupGenericSettingsController(genericSettingController)); + + const simpleScanningInputController = new ScanInputsSimpleController(settingsController); + simpleScanningInputController.prepare(); + + await Promise.all(preparePromises); + + document.documentElement.dataset.loaded = 'true'; + + const settingsDisplayController = new SettingsDisplayController(settingsController, modalController); + settingsDisplayController.prepare(); + } catch (e) { + yomichan.logError(e); + } +})(); diff --git a/ext/bg/settings2.html b/ext/bg/settings2.html index 1cf25934..7e2e2e35 100644 --- a/ext/bg/settings2.html +++ b/ext/bg/settings2.html @@ -186,7 +186,7 @@ </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="guide.html" target="_blank" rel="noopener">welcome guide</a> on browser startup</div> + <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> diff --git a/ext/bg/welcome.html b/ext/bg/welcome.html new file mode 100644 index 00000000..91b58bc9 --- /dev/null +++ b/ext/bg/welcome.html @@ -0,0 +1,372 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <title>Welcome to Yomichan!</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="/bg/css/settings2.css"> + <style> +.inline-icon { + position: relative; + width: calc(1em * (16 / var(--font-size-default-no-units))); + height: calc(1em * (16 / var(--font-size-default-no-units))); + top: calc(1em * (3 / var(--font-size-default-no-units))); +} +.dictionary-info { + display: flex; + flex-flow: row nowrap; + align-items: center; +} +.dictionary-info-label { + margin-left: 1em; +} + </style> +</head> +<body> + +<!-- Main content --> +<div class="content-outer"><div class="content"> +<div class="content-center"> + + <span tabindex="-1" id="content-scroll-focus"></span> + + <h1>Welcome to Yomichan!</h1> + + <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="/mixed/img/yomichan-icon.svg" class="inline-icon" alt=""> <em>Yomichan icon</em> 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="/mixed/img/cog.svg" class="inline-icon" alt=""> <em>cog</em> button will open the settings 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="/mixed/img/magnifying-glass.svg" class="inline-icon" alt=""> <em>magnifying glass</em> button will open a search 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="/mixed/img/question-mark-circle.svg" class="inline-icon" alt=""> <em>question mark</em> button will open a page + with some general information about Yomichan. + </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"> + Yomichan 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://foosoft.net/projects/yomichan/#dictionaries" target="_blank" rel="noopener noreferrer">Yomichan homepage</a>, + allowing you to choose the dictionaries most relevant for you. + Dictionaries can be configured using the button below, + or later from the the <a href="settings2.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 class="icon-button"><span class="icon-button-inner"><span class="icon-button-icon" data-icon="right-arrow"></span></span></button> + </div> + </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 the scanning modifier key. + The default key is <kbd>Shift</kbd>, which can be 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="/mixed/img/play-audio.svg" class="inline-icon" alt=""> <em>speaker icon</em> of an entry in the popup 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> + <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="settings2.html" rel="noopener">Settings</a> page. + </div></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-left"> + <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" 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">Scan modifier key</div> + <div class="settings-item-description">Hold a key while moving the cursor to scan text.</div> + </div> + <div class="settings-item-right"> + <select id="main-scan-modifier-key"></select> + </div> + </div> + </div> + <div class="settings-item"><div class="settings-item-inner"> + <div class="settings-item-left"> + <div class="settings-item-label">Scan using middle mouse button</div> + <div class="settings-item-description">Hold the middle mouse button while moving the cursor to scan text.</div> + </div> + <div class="settings-item-right"> + <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 key or button is required for scanning, the popup will hide automatically.</div> + </div> + <div class="settings-item-right"> + <label class="toggle"><input type="checkbox" data-setting="scanning.autoHideResults" data-transform="setVisibility" data-ancestor-distance="-1" data-relative-selector="#auto-hide-search-popup-options" data-visbility-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">Popup auto-hide 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">When no key or button is required for scanning, the delay before scanning occurs.</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> + <div class="settings-item-description">Adjust the style of the popup.</div> + </div> + <div class="settings-item-right"> + <div class="settings-item-group"> + <div class="settings-item-group-item"> + <div class="settings-item-group-item-label">Body</div> + <select data-setting="general.popupTheme" class="short-width short-height"> + <option value="default">Light</option> + <option value="dark">Dark</option> + </select> + </div> + <div class="settings-item-group-item"> + <div class="settings-item-group-item-label">Shadow</div> + <select data-setting="general.popupOuterTheme" class="short-width short-height"> + <option value="auto">Auto-detect</option> + <option value="default">Light</option> + <option value="dark">Dark</option> + </select> + </div> + </div> + </div> + </div></div> + <a href="settings2.html" rel="noopener" class="settings-item settings-item-button"><div class="settings-item-inner"> + <div class="settings-item-left"> + <div class="settings-item-label">View more settings on the Settings page</div> + </div> + <div class="settings-item-right open-panel-button-container"> + <button class="icon-button"><span class="icon-button-inner"><span class="icon-button-icon" data-icon="right-arrow"></span></span></button> + </div> + </div></a> + </div> + + <div class="footer-padding"></div> + +</div> +</div></div> + + +<!-- Auxiliary content --> +<div class="status-footer-container"><div class="status-footer-container2"> + <div class="status-footer"> + <div class="status-footer-header"><div class="status-footer-header-label">Tasks in progress:</div><a class="status-footer-header-close">Close</a></div> + <div class="status-footer-item dictionary-delete-progress" hidden> + <div class="progress-labels"><div class="progress-info"></div><div class="progress-status"></div></div> + <div class="progress-bar-track"><div class="progress-bar danger"></div></div> + </div> + <div class="status-footer-item dictionary-import-progress" hidden> + <div class="progress-labels"><div class="progress-info"></div><div class="progress-status"></div></div> + <div class="progress-bar-track"><div class="progress-bar"></div></div> + </div> + </div> +</div></div> + +<div id="popup-menus"></div> + + +<!-- Dictionary modals --> +<div id="dictionaries" class="modal-container" tabindex="-1" role="dialog"><div class="modal-content"> + <div class="modal-header"><div class="modal-title">Dictionaries</div></div> + <div class="modal-body"> + <div class="settings-item"> + <div class="settings-item-inner"> + <div class="settings-item-left"> + <div class="settings-item-label"> + Enable support for prefix wildcard searches + <a class="more-toggle more-only" data-parent-distance="4">(?)</a> + </div> + </div> + <div class="settings-item-right"> + <label class="toggle"><input type="checkbox" data-setting="global.database.prefixWildcardsSupported" data-scope="global"><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> + In order for dictionaries to support searches using prefix wildcards on the search page, + some additional data must be stored in the database. + Enabling this option will include this extra data for any new dictionaries that are imported. + </p> + <p class="warning-text"> + This option will not change any dictionaries that are already imported; + they must be re-imported for the option to take effect. + </p> + <p> + <a class="more-toggle" data-parent-distance="3">Hide…</a> + </p> + </div> + </div> + + <div class="settings-item"><div class="settings-item-inner"> + <div class="settings-item-left"> + <div class="settings-item-label"> + More dictionary settings are available on the <a href="settings2.html" rel="noopener">Settings</a> page + </div> + </div> + </div></div> + + <div class="warning-text margin-above no-dictionaries-installed-warning" hidden> + No dictionaries have been installed yet. + Visit the <a href="https://foosoft.net/projects/yomichan/#dictionaries" target="_blank" rel="noopener noreferrer">Yomichan homepage</a> + for a list free dictionaries or click the <em>Import</em> button below to select a dictionary file to import. + </div> + <div id="dictionary-error" class="danger-text margin-above" hidden></div> + <div id="dictionary-list" class="dictionary-list"></div> + <div id="dictionary-list-extra" class="dictionary-list"></div> + + <div hidden><input type="file" id="dictionary-import-file-input" accept=".zip,application/zip" multiple></div> + </div> + <div class="modal-body-addon dictionary-delete-progress" hidden> + <div class="progress-labels"><div class="progress-info"></div><div class="progress-status"></div></div> + <div class="progress-bar-track"><div class="progress-bar danger"></div></div> + </div> + <div class="modal-body-addon dictionary-import-progress" hidden> + <div class="progress-labels"><div class="progress-info"></div><div class="progress-status"></div></div> + <div class="progress-bar-track"><div class="progress-bar"></div></div> + </div> + <div class="modal-footer"> + <button class="low-emphasis danger dictionary-database-mutating-input" id="dictionary-delete-all-button">Delete All</button> + <button class="low-emphasis dictionary-database-mutating-input" id="dictionary-import-file-button">Import</button> + <button data-modal-action="hide">Close</button> + </div> +</div></div> + +<div id="dictionary-confirm-delete" class="modal-container" tabindex="-1" role="dialog"><div class="modal-content modal-content-small"> + <div class="modal-header"><div class="modal-title">Confirm Dictionary Deletion</div></div> + <div class="modal-body"> + <p>Are you sure you want to delete the dictionary:</p> + <p><strong id="dictionary-confirm-delete-name"></strong>?</p> + <p class="danger-text">This action cannot be undone.</p> + </div> + <div class="modal-footer"> + <button class="low-emphasis" data-modal-action="hide">Cancel</button> + <button class="danger" data-modal-action="hide" id="dictionary-confirm-delete-button">Delete</button> + </div> +</div></div> + +<div id="dictionary-confirm-delete-all" class="modal-container" tabindex="-1" role="dialog"><div class="modal-content modal-content-small"> + <div class="modal-header"><div class="modal-title">Confirm Dictionary Deletion</div></div> + <div class="modal-body"> + <p>Are you sure you want to delete <strong>all dictionaries</strong>?</p> + <p class="danger-text">This action cannot be undone.</p> + </div> + <div class="modal-footer"> + <button class="low-emphasis" data-modal-action="hide">Cancel</button> + <button class="danger" data-modal-action="hide" id="dictionary-confirm-delete-all-button">Delete</button> + </div> +</div></div> + + +<!-- Dictionary templates --> +<template id="dictionary-template"><div class="settings-item"> + <div class="settings-item-inner"> + <div class="settings-item-left"> + <div class="settings-item-label dictionary-info"> + <label class="toggle"><input type="checkbox" class="dictionary-enabled"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label> + <span class="dictionary-info-label"><strong class="dictionary-title"></strong> <span class="light dictionary-version"></span></span> + </div> + </div> + <div class="settings-item-right"> + <button class="icon-button dictionary-menu-button" data-menu="dictionary-menu" data-menu-position="below,left"><span class="icon-button-inner"><span class="icon-button-icon" data-icon="kebab-menu"></span></span></button> + </div> + </div> +</div></template> + +<template id="dictionary-menu-template"><div class="popup-menu-container" tabindex="-1" role="dialog"><div class="popup-menu"> + <button class="popup-menu-item" data-menu-action="delete">Delete</button> +</div></div></template> + + +<!-- Scripts --> +<script src="/mixed/lib/jszip.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/cache-map.js"></script> +<script src="/mixed/js/document-util.js"></script> +<script src="/mixed/js/dom-data-binder.js"></script> +<script src="/mixed/js/html-template-collection.js"></script> +<script src="/mixed/js/object-property-accessor.js"></script> +<script src="/mixed/js/selector-observer.js"></script> +<script src="/mixed/js/task-accumulator.js"></script> + +<script src="/bg/js/database.js"></script> +<script src="/bg/js/dictionary-database.js"></script> +<script src="/bg/js/dictionary-importer.js"></script> +<script src="/bg/js/json-schema.js"></script> +<script src="/bg/js/media-utility.js"></script> + +<script src="/bg/js/settings/dictionary-controller.js"></script> +<script src="/bg/js/settings/dictionary-import-controller.js"></script> +<script src="/bg/js/settings/generic-setting-controller.js"></script> +<script src="/bg/js/settings/modal-controller.js"></script> +<script src="/bg/js/settings/popup-elements.js"></script> +<script src="/bg/js/settings/popup-menu.js"></script> +<script src="/bg/js/settings/scan-inputs-simple-controller.js"></script> +<script src="/bg/js/settings/settings-controller.js"></script> + +<script src="/bg/js/settings2/settings-display-controller.js"></script> + +<script src="/bg/js/welcome-main.js"></script> + +</body> +</html> |