diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-11-19 18:37:02 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-19 18:37:02 -0500 |
commit | e5255a03e68574afecced794f8092bf76ec241a3 (patch) | |
tree | 0f27eeb7f733765823b9b99921893d998f9a1664 /ext | |
parent | b0a565062524f74b973071f259a2c0d7a577c372 (diff) |
Context popup improvements (#1039)
* Refactor context-main.js
* Simplify tags
* Use flex layout
* Use image masks for icons, update styles
* Remove old classes
* Add profile button
* Add support for profile selection
* Add title
* Swap the options and search link order
* Fix title
Diffstat (limited to 'ext')
-rw-r--r-- | ext/bg/context.html | 16 | ||||
-rw-r--r-- | ext/bg/css/context.css | 75 | ||||
-rw-r--r-- | ext/bg/js/context-main.js | 158 |
3 files changed, 183 insertions, 66 deletions
diff --git a/ext/bg/context.html b/ext/bg/context.html index 2fa2f520..1eb9c058 100644 --- a/ext/bg/context.html +++ b/ext/bg/context.html @@ -2,7 +2,8 @@ <html lang="en"> <head> <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width,initial-scale=1" /> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <title>Yomichan Action Popup</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"> @@ -19,13 +20,18 @@ <input type="checkbox" id="enable-search"> <div class="toggle-group"> <span class="toggle-on">On</span> - <span class="btnx btn-defaulxt toggle-off">Off</span> - <span class="btnx xbtn-default toggle-handle"></span> + <span class="toggle-off">Off</span> + <span class="toggle-handle"></span> </div> </label> <div class="nav-button-container"> - <a class="nav-button action-open-search" data-icon="magnifying-glass" title="Search (Alt + Insert) (Middle click to open in new tab)"></a> + <button class="nav-button action-select-profile" data-icon="profile" title="Change primary profile"> + <span class="profile-select-container"><select class="profile-select" id="profile-select"> + <optgroup label="Primary Profile" id="profile-select-option-group"></optgroup> + </select></span> + </button> <a class="nav-button action-open-options" data-icon="cog" title="Options (Middle click to open in new tab)"></a> + <a class="nav-button action-open-search" data-icon="magnifying-glass" title="Search (Alt + Insert) (Middle click to open in new tab)"></a> <a class="nav-button action-open-help" data-icon="question-mark" title="Help"></a> </div> </div> @@ -33,7 +39,7 @@ <div id="full"> <h3 id="extension-info">Yomichan</h3> <label class="link-group"> - <span class="link-group-icon"><input type="checkbox" id="enable-search2" /></span><span class="link-group-label">Enable content scanning</span> + <span class="link-group-icon"><input type="checkbox" id="enable-search2"></span><span class="link-group-label">Enable content scanning</span> </label> <a class="link-group action-open-options"> <span class="link-group-icon" data-icon="chevron"></span><span class="link-group-label">Options</span> diff --git a/ext/bg/css/context.css b/ext/bg/css/context.css index 2d42dd16..c1e88ef5 100644 --- a/ext/bg/css/context.css +++ b/ext/bg/css/context.css @@ -35,7 +35,9 @@ label { } #mini { - text-align: center; + display: flex; + flex-flow: column nowrap; + align-items: center; } #full { display: none; @@ -243,10 +245,17 @@ body[data-loaded=true] .toggle-group { display: block; width: 16px; height: 16px; - background-position: center center; - background-size: 16px 16px; - background-repeat: no-repeat; box-sizing: content-box; + background-color: #333333; + mask-repeat: no-repeat; + mask-position: center center; + mask-mode: alpha; + mask-size: 16px 16px; + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center center; + -webkit-mask-mode: alpha; + -webkit-mask-size: 16px 16px; + pointer-events: none; } .nav-button:hover { z-index: 1; @@ -264,19 +273,67 @@ body[data-loaded=true] .toggle-group { outline: none; } .nav-button[data-icon=magnifying-glass]::after { - background-image: url(/mixed/img/magnifying-glass.svg); + mask-image: url(/mixed/img/magnifying-glass.svg); + -webkit-mask-image: url(/mixed/img/magnifying-glass.svg); } .nav-button[data-icon=cog]::after { - background-image: url(/mixed/img/cog.svg); + mask-image: url(/mixed/img/cog.svg); + -webkit-mask-image: url(/mixed/img/cog.svg); } .nav-button[data-icon=question-mark]::after { - background-image: url(/mixed/img/question-mark-circle.svg); + mask-image: url(/mixed/img/question-mark-circle.svg); + -webkit-mask-image: url(/mixed/img/question-mark-circle.svg); } -.nav-button:first-of-type { +.nav-button[data-icon=profile]::after { + mask-image: url(/mixed/img/profile.svg); + -webkit-mask-image: url(/mixed/img/profile.svg); +} +.nav-button:first-child { border-top-left-radius: 3px; border-bottom-left-radius: 3px; } -.nav-button:last-of-type { +.nav-button:last-child { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } + +.action-select-profile { + position: relative; +} +.profile-select-container { + position: absolute; + left: -1px; + top: -1px; + right: -1px; + bottom: -1px; +} +select.profile-select { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + box-sizing: border-box; + border: 0; + margin: 0; + padding: 0.375em; + appearance: none; + -moz-appearance: none; + -webkit-appearance: none; + opacity: 0; + outline: none; + cursor: pointer; + font-size: 14px; +} +.profile-select optgroup { + color: #666666; + font-weight: normal; + font-style: normal; + background-color: #f2f2f2; +} +.profile-select option { + color: #333333; + font-weight: normal; + font-style: normal; + background-color: initial; +} diff --git a/ext/bg/js/context-main.js b/ext/bg/js/context-main.js index 72abe554..e7cff04c 100644 --- a/ext/bg/js/context-main.js +++ b/ext/bg/js/context-main.js @@ -19,73 +19,127 @@ * api */ -function showExtensionInfo(manifest) { - const node = document.getElementById('extension-info'); - if (node === null) { return; } +class DisplayController { + constructor() { + this._optionsFull = null; + } - node.textContent = `${manifest.name} v${manifest.version}`; -} + async prepare() { + const manifest = chrome.runtime.getManifest(); + + this._showExtensionInfo(manifest); + this._setupEnvironment(); + this._setupButtonEvents('.action-open-search', 'search', chrome.runtime.getURL('/bg/search.html')); + this._setupButtonEvents('.action-open-options', 'options', chrome.runtime.getURL(manifest.options_ui.page)); + this._setupButtonEvents('.action-open-help', 'help', 'https://foosoft.net/projects/yomichan/'); + + const optionsFull = await api.optionsGetFull(); + this._optionsFull = optionsFull; -function setupButtonEvents(selector, command, url) { - const nodes = document.querySelectorAll(selector); - for (const node of nodes) { - node.addEventListener('click', (e) => { - if (e.button !== 0) { return; } - api.commandExec(command, {mode: e.ctrlKey ? 'newTab' : 'existingOrNewTab'}); - e.preventDefault(); - }, false); - node.addEventListener('auxclick', (e) => { - if (e.button !== 1) { return; } - api.commandExec(command, {mode: 'newTab'}); - e.preventDefault(); - }, false); - - if (typeof url === 'string') { - node.href = url; - node.target = '_blank'; - node.rel = 'noopener'; + const {profiles, profileCurrent} = optionsFull; + const primaryProfile = (profileCurrent >= 0 && profileCurrent < profiles.length) ? profiles[profileCurrent] : null; + if (primaryProfile !== null) { + this._setupOptions(primaryProfile); } + + this._updateProfileSelect(profiles, profileCurrent); + + setTimeout(() => { + document.body.dataset.loaded = 'true'; + }, 10); } -} -async function setupEnvironment() { - // Firefox mobile opens this page as a full webpage. - const {browser} = await api.getEnvironmentInfo(); - document.documentElement.dataset.mode = (browser === 'firefox-mobile' ? 'full' : 'mini'); -} + // Private + + _showExtensionInfo(manifest) { + const node = document.getElementById('extension-info'); + if (node === null) { return; } + + node.textContent = `${manifest.name} v${manifest.version}`; + } + + _setupButtonEvents(selector, command, url) { + const nodes = document.querySelectorAll(selector); + for (const node of nodes) { + node.addEventListener('click', (e) => { + if (e.button !== 0) { return; } + api.commandExec(command, {mode: e.ctrlKey ? 'newTab' : 'existingOrNewTab'}); + e.preventDefault(); + }, false); + node.addEventListener('auxclick', (e) => { + if (e.button !== 1) { return; } + api.commandExec(command, {mode: 'newTab'}); + e.preventDefault(); + }, false); + + if (typeof url === 'string') { + node.href = url; + node.target = '_blank'; + node.rel = 'noopener'; + } + } + } + + async _setupEnvironment() { + // Firefox mobile opens this page as a full webpage. + const {browser} = await api.getEnvironmentInfo(); + document.documentElement.dataset.mode = (browser === 'firefox-mobile' ? 'full' : 'mini'); + } + + _setupOptions({options}) { + const extensionEnabled = options.general.enable; + const onToggleChanged = () => api.commandExec('toggle'); + for (const toggle of document.querySelectorAll('#enable-search,#enable-search2')) { + toggle.checked = extensionEnabled; + toggle.addEventListener('change', onToggleChanged, false); + } + } + + _updateProfileSelect(profiles, profileCurrent) { + const select = document.querySelector('#profile-select'); + const optionGroup = document.querySelector('#profile-select-option-group'); + const fragment = document.createDocumentFragment(); + for (let i = 0, ii = profiles.length; i < ii; ++i) { + const {name} = profiles[i]; + const option = document.createElement('option'); + option.textContent = name; + option.value = `${i}`; + fragment.appendChild(option); + } + optionGroup.textContent = ''; + optionGroup.appendChild(fragment); + select.value = `${profileCurrent}`; + + select.addEventListener('change', this._onProfileSelectChange.bind(this), false); + } -async function setupOptions() { - const optionsContext = { - depth: 0, - url: window.location.href - }; - const options = await api.optionsGet(optionsContext); - - const extensionEnabled = options.general.enable; - const onToggleChanged = () => api.commandExec('toggle'); - for (const toggle of document.querySelectorAll('#enable-search,#enable-search2')) { - toggle.checked = extensionEnabled; - toggle.addEventListener('change', onToggleChanged, false); + _onProfileSelectChange(e) { + const value = parseInt(e.currentTarget.value, 10); + if (typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= this._optionsFull.profiles.length) { + this._setPrimaryProfileIndex(value); + } } - setTimeout(() => { - document.body.dataset.loaded = 'true'; - }, 10); + async _setPrimaryProfileIndex(value) { + return await api.modifySettings( + [{ + action: 'set', + path: 'profileCurrent', + value, + scope: 'global' + }] + ); + } } (async () => { api.forwardLogsToBackend(); await yomichan.backendReady(); - const manifest = chrome.runtime.getManifest(); - api.logIndicatorClear(); - showExtensionInfo(manifest); - setupEnvironment(); - setupOptions(); - setupButtonEvents('.action-open-search', 'search', chrome.runtime.getURL('/bg/search.html')); - setupButtonEvents('.action-open-options', 'options', chrome.runtime.getURL(manifest.options_ui.page)); - setupButtonEvents('.action-open-help', 'help', 'https://foosoft.net/projects/yomichan/'); + + const displayController = new DisplayController(); + displayController.prepare(); yomichan.ready(); })(); |