summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-11-19 18:37:02 -0500
committerGitHub <noreply@github.com>2020-11-19 18:37:02 -0500
commite5255a03e68574afecced794f8092bf76ec241a3 (patch)
tree0f27eeb7f733765823b9b99921893d998f9a1664
parentb0a565062524f74b973071f259a2c0d7a577c372 (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
-rw-r--r--ext/bg/context.html16
-rw-r--r--ext/bg/css/context.css75
-rw-r--r--ext/bg/js/context-main.js158
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)&#10;(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&#10;(Middle click to open in new tab)"></a>
+ <a class="nav-button action-open-search" data-icon="magnifying-glass" title="Search (Alt + Insert)&#10;(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();
})();