From 8766744aa4a94193dd03bba39086e4522914e8ef Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 16 Jan 2021 10:22:24 -0500 Subject: [PATCH] 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 --- ext/bg/css/settings2.css | 2 +- ext/bg/data/options-schema.json | 52 ++++++++ ext/bg/js/backend.js | 71 +++++++--- ext/bg/js/options.js | 11 ++ .../js/settings/generic-setting-controller.js | 5 + .../js/settings2/popup-window-controller.js | 38 ++++++ ext/bg/js/settings2/settings-main.js | 4 + ext/bg/settings2.html | 125 +++++++++++++++++- test/test-options-util.js | 10 ++ 9 files changed, 295 insertions(+), 23 deletions(-) create mode 100644 ext/bg/js/settings2/popup-window-controller.js 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 . + */ + +/* 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 @@ Popup Appearance Position & Size - Window + Window Audio Text Parsing Sentence Parsing @@ -921,11 +921,12 @@ -
+ -
+
@@ -989,6 +990,123 @@
+
+
+
Size
+
Control the size of the window, in pixels.
+
+
+
+
+
Width
+ +
+
+
Height
+ +
+
+
+
+
+
+
Left position
+
Control the left position of the window, in pixels.
+
+
+
+ +
+
Mode
+ +
+
+
+
+
+
+
Top position
+
Control the top position of the window, in pixels.
+
+
+
+ +
+
Mode
+ +
+
+
+
+
+
+
Window style
+
Change the appearance of the window.
+
+
+
+
+
Type
+ +
+
+
State
+ +
+
+
+
@@ -2971,6 +3089,7 @@ + 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' } }; }