aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-01-16 10:22:24 -0500
committerGitHub <noreply@github.com>2021-01-16 10:22:24 -0500
commit8766744aa4a94193dd03bba39086e4522914e8ef (patch)
treebfb4a15e264c1fa4f9740bbd763a255e164a51e1
parentdc4d659184a61a55083e201438bff7732acece1b (diff)
Popup window options (#1245)
* Add popupWindow options * Add toBoolean converter * Add settings * Use new options * Add test link * Fix window state not working * Make the window section advanced only
-rw-r--r--ext/bg/css/settings2.css2
-rw-r--r--ext/bg/data/options-schema.json52
-rw-r--r--ext/bg/js/backend.js71
-rw-r--r--ext/bg/js/options.js11
-rw-r--r--ext/bg/js/settings/generic-setting-controller.js5
-rw-r--r--ext/bg/js/settings2/popup-window-controller.js38
-rw-r--r--ext/bg/js/settings2/settings-main.js4
-rw-r--r--ext/bg/settings2.html125
-rw-r--r--test/test-options-util.js10
9 files changed, 295 insertions, 23 deletions
diff --git a/ext/bg/css/settings2.css b/ext/bg/css/settings2.css
index b41ea7ea..fe9f0e6b 100644
--- a/ext/bg/css/settings2.css
+++ b/ext/bg/css/settings2.css
@@ -230,7 +230,7 @@ h3 {
font-size: calc(1em / 1.125);
color: var(--text-color-light);
}
-.heading-link-light {
+a.heading-link-light {
color: var(--text-color-light);
}
.heading-description,
diff --git a/ext/bg/data/options-schema.json b/ext/bg/data/options-schema.json
index 405d62a9..def279cc 100644
--- a/ext/bg/data/options-schema.json
+++ b/ext/bg/data/options-schema.json
@@ -63,6 +63,7 @@
"type": "object",
"required": [
"general",
+ "popupWindow",
"audio",
"scanning",
"translation",
@@ -288,6 +289,57 @@
}
}
},
+ "popupWindow": {
+ "type": "object",
+ "required": [
+ "width",
+ "height",
+ "left",
+ "top",
+ "useLeft",
+ "useTop",
+ "windowType",
+ "windowState"
+ ],
+ "properties": {
+ "width": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 400
+ },
+ "height": {
+ "type": "integer",
+ "minimum": 0,
+ "default": 250
+ },
+ "left": {
+ "type": "integer",
+ "default": 0
+ },
+ "top": {
+ "type": "integer",
+ "default": 0
+ },
+ "useLeft": {
+ "type": "boolean",
+ "default": false
+ },
+ "useTop": {
+ "type": "boolean",
+ "default": false
+ },
+ "windowType": {
+ "type": "string",
+ "enum": ["normal", "popup"],
+ "default": "popup"
+ },
+ "windowState": {
+ "type": "string",
+ "enum": ["normal", "maximized", "fullscreen"],
+ "default": "normal"
+ }
+ }
+ },
"audio": {
"type": "object",
"required": [
diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js
index 11a17381..d5e5b086 100644
--- a/ext/bg/js/backend.js
+++ b/ext/bg/js/backend.js
@@ -818,25 +818,12 @@ class Backend {
// Create a new window
const options = this.getOptions({current: true});
- const {popupWidth, popupHeight} = options.general;
- const popupWindow = await new Promise((resolve, reject) => {
- chrome.windows.create(
- {
- url: baseUrl,
- width: popupWidth,
- height: popupHeight,
- type: 'popup'
- },
- (result) => {
- const error = chrome.runtime.lastError;
- if (error) {
- reject(new Error(error.message));
- } else {
- resolve(result);
- }
- }
- );
- });
+ const createData = this._getSearchPopupWindowCreateData(baseUrl, options);
+ const {popupWindow: {windowState}} = options;
+ const popupWindow = await this._createWindow(createData);
+ if (windowState !== 'normal') {
+ await this._updateWindow(popupWindow.id, {state: windowState});
+ }
const {tabs} = popupWindow;
if (tabs.length === 0) {
@@ -856,6 +843,52 @@ class Backend {
return {tab, created: true};
}
+ _getSearchPopupWindowCreateData(url, options) {
+ const {popupWindow: {width, height, left, top, useLeft, useTop, windowType}} = options;
+ return {
+ url,
+ width,
+ height,
+ left: useLeft ? left : void 0,
+ top: useTop ? top : void 0,
+ type: windowType,
+ state: 'normal'
+ };
+ }
+
+ _createWindow(createData) {
+ return new Promise((resolve, reject) => {
+ chrome.windows.create(
+ createData,
+ (result) => {
+ const error = chrome.runtime.lastError;
+ if (error) {
+ reject(new Error(error.message));
+ } else {
+ resolve(result);
+ }
+ }
+ );
+ });
+ }
+
+ _updateWindow(windowId, updateInfo) {
+ return new Promise((resolve, reject) => {
+ chrome.windows.update(
+ windowId,
+ updateInfo,
+ (result) => {
+ const error = chrome.runtime.lastError;
+ if (error) {
+ reject(new Error(error.message));
+ } else {
+ resolve(result);
+ }
+ }
+ );
+ });
+ }
+
_updateSearchQuery(tabId, text, animate) {
return this._sendMessageTabPromise(
tabId,
diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js
index 964c346c..026d75c5 100644
--- a/ext/bg/js/options.js
+++ b/ext/bg/js/options.js
@@ -689,6 +689,7 @@ class OptionsUtil {
// Changed general.popupActionBarLocation.
// Added inputs.hotkeys.
// Added anki.suspendNewCards.
+ // Added popupWindow.
for (const profile of options.profiles) {
profile.options.translation.textReplacements = {
searchOriginal: true,
@@ -735,6 +736,16 @@ class OptionsUtil {
]
};
profile.options.anki.suspendNewCards = false;
+ profile.options.popupWindow = {
+ width: profile.options.general.popupWidth,
+ height: profile.options.general.popupHeight,
+ left: 0,
+ top: 0,
+ useLeft: false,
+ useTop: false,
+ windowType: 'popup',
+ windowState: 'normal'
+ };
}
return options;
}
diff --git a/ext/bg/js/settings/generic-setting-controller.js b/ext/bg/js/settings/generic-setting-controller.js
index 0d24c429..7d6fc2e6 100644
--- a/ext/bg/js/settings/generic-setting-controller.js
+++ b/ext/bg/js/settings/generic-setting-controller.js
@@ -36,6 +36,7 @@ class GenericSettingController {
['splitTags', this._splitTags.bind(this)],
['joinTags', this._joinTags.bind(this)],
['toNumber', this._toNumber.bind(this)],
+ ['toBoolean', this._toBoolean.bind(this)],
['toString', this._toString.bind(this)],
['conditionalConvert', this._conditionalConvert.bind(this)]
]);
@@ -206,6 +207,10 @@ class GenericSettingController {
return DOMDataBinder.convertToNumber(value, constraints);
}
+ _toBoolean(value) {
+ return (value === 'true');
+ }
+
_toString(value) {
return `${value}`;
}
diff --git a/ext/bg/js/settings2/popup-window-controller.js b/ext/bg/js/settings2/popup-window-controller.js
new file mode 100644
index 00000000..cc83db68
--- /dev/null
+++ b/ext/bg/js/settings2/popup-window-controller.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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
+ * api
+ */
+
+class PopupWindowController {
+ prepare() {
+ const testLink = document.querySelector('#test-window-open-link');
+ testLink.addEventListener('click', this._onTestWindowOpenLinkClick.bind(this), false);
+ }
+
+ // Private
+
+ _onTestWindowOpenLinkClick(e) {
+ e.preventDefault();
+ this._testWindowOpen();
+ }
+
+ async _testWindowOpen() {
+ await api.getOrCreateSearchPopup({focus: true});
+ }
+}
diff --git a/ext/bg/js/settings2/settings-main.js b/ext/bg/js/settings2/settings-main.js
index f2852ab1..76a40d81 100644
--- a/ext/bg/js/settings2/settings-main.js
+++ b/ext/bg/js/settings2/settings-main.js
@@ -29,6 +29,7 @@
* ModalController
* NestedPopupsController
* PopupPreviewController
+ * PopupWindowController
* ProfileController
* ScanInputsController
* ScanInputsSimpleController
@@ -132,6 +133,9 @@ async function setupGenericSettingsController(genericSettingController) {
const keyboardShortcutController = new KeyboardShortcutController(settingsController);
keyboardShortcutController.prepare();
+ const popupWindowController = new PopupWindowController();
+ popupWindowController.prepare();
+
await Promise.all(preparePromises);
document.documentElement.dataset.loaded = 'true';
diff --git a/ext/bg/settings2.html b/ext/bg/settings2.html
index 08dc92d5..33edca69 100644
--- a/ext/bg/settings2.html
+++ b/ext/bg/settings2.html
@@ -28,7 +28,7 @@
<a href="#!popup" class="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="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-size" class="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 &amp; Size</span></a>
- <a href="#!window" class="outline-item"><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="#!window" class="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="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>
<a href="#!text-parsing" class="outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="text-parsing"></span></span><span class="outline-item-label">Text Parsing</span></a>
<a href="#!sentence-parsing" class="outline-item advanced-only"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="sentence-parsing"></span></span><span class="outline-item-label">Sentence Parsing</span></a>
@@ -921,11 +921,12 @@
</div>
<!-- Window -->
- <div class="heading-container">
+ <div class="heading-container advanced-only">
<div class="heading-container-icon"><span class="icon" data-icon="window"></span></div>
<div class="heading-container-left"><h2 id="window"><a href="#!window">Window</a></h2></div>
+ <div class="heading-container-right"><a class="heading-link-light" id="test-window-open-link">Open&hellip;</a></div>
</div>
- <div class="settings-group">
+ <div class="settings-group advanced-only">
<div class="settings-item">
<div class="settings-item-inner">
<div class="settings-item-left">
@@ -989,6 +990,123 @@
<input type="number" min="0" step="1" data-setting="general.maximumClipboardSearchLength">
</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">Size</div>
+ <div class="settings-item-description">Control the size of the window, in pixels.</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">Width</div>
+ <input type="number" class="short-width short-height" min="0" step="1" data-setting="popupWindow.width">
+ </div>
+ <div class="settings-item-group-item">
+ <div class="settings-item-group-item-label">Height</div>
+ <input type="number" class="short-width short-height" min="0" step="1" data-setting="popupWindow.height">
+ </div>
+ </div>
+ </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">Left position</div>
+ <div class="settings-item-description">Control the left position of the window, in pixels.</div>
+ </div>
+ <div class="settings-item-right">
+ <div class="settings-item-group">
+ <div class="settings-item-group-item" id="popup-window-left-container" hidden>
+ <div class="settings-item-group-item-label">x</div>
+ <input type="number" class="short-width short-height" step="1" data-setting="popupWindow.left">
+ </div>
+ <div class="settings-item-group-item">
+ <div class="settings-item-group-item-label">Mode</div>
+ <select class="short-width short-height" data-setting="popupWindow.useLeft"
+ data-transform='[
+ {
+ "step": "pre",
+ "type": "toBoolean"
+ },
+ {
+ "type": "setVisibility",
+ "selector": "#popup-window-left-container",
+ "condition": {"op": "===", "value": true}
+ },
+ {
+ "step": "post",
+ "type": "toString"
+ }
+ ]'
+ >
+ <option value="false">Auto</option>
+ <option value="true">Manual</option>
+ </select>
+ </div>
+ </div>
+ </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">Top position</div>
+ <div class="settings-item-description">Control the top position of the window, in pixels.</div>
+ </div>
+ <div class="settings-item-right">
+ <div class="settings-item-group">
+ <div class="settings-item-group-item" id="popup-window-top-container" hidden>
+ <div class="settings-item-group-item-label">y</div>
+ <input type="number" class="short-width short-height" step="1" data-setting="popupWindow.top">
+ </div>
+ <div class="settings-item-group-item">
+ <div class="settings-item-group-item-label">Mode</div>
+ <select class="short-width short-height" data-setting="popupWindow.useTop"
+ data-transform='[
+ {
+ "step": "pre",
+ "type": "toBoolean"
+ },
+ {
+ "type": "setVisibility",
+ "selector": "#popup-window-top-container",
+ "condition": {"op": "===", "value": true}
+ },
+ {
+ "step": "post",
+ "type": "toString"
+ }
+ ]'
+ >
+ <option value="false">Auto</option>
+ <option value="true">Manual</option>
+ </select>
+ </div>
+ </div>
+ </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">Window style</div>
+ <div class="settings-item-description">Change the appearance of the window.</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">Type</div>
+ <select class="short-width short-height" data-setting="popupWindow.windowType">
+ <option value="normal">Normal</option>
+ <option value="popup">Popup</option>
+ </select>
+ </div>
+ <div class="settings-item-group-item">
+ <div class="settings-item-group-item-label">State</div>
+ <select class="short-width short-height" data-setting="popupWindow.windowState">
+ <option value="normal">Normal</option>
+ <option value="maximized">Maximized</option>
+ <option value="fullscreen">Fullscreen</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ </div></div>
</div>
<!-- Audio -->
@@ -2971,6 +3089,7 @@
<script src="/bg/js/settings2/keyboard-shortcuts-controller.js"></script>
<script src="/bg/js/settings2/nested-popups-controller.js"></script>
+<script src="/bg/js/settings2/popup-window-controller.js"></script>
<script src="/bg/js/settings2/secondary-search-dictionary-controller.js"></script>
<script src="/bg/js/settings2/sentence-termination-characters-controller.js"></script>
<script src="/bg/js/settings2/settings-display-controller.js"></script>
diff --git a/test/test-options-util.js b/test/test-options-util.js
index f27fbcd4..d6dae940 100644
--- a/test/test-options-util.js
+++ b/test/test-options-util.js
@@ -457,6 +457,16 @@ function createProfileOptionsUpdatedTestData1() {
{action: 'viewNote', key: 'KeyV', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true},
{action: 'copyHostSelection', key: 'KeyC', modifiers: ['ctrl'], scopes: ['popup', 'search'], enabled: true}
]
+ },
+ popupWindow: {
+ width: 400,
+ height: 250,
+ left: 0,
+ top: 0,
+ useLeft: false,
+ useTop: false,
+ windowType: 'popup',
+ windowState: 'normal'
}
};
}