summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/css/popup-preview.css6
-rw-r--r--ext/data/schemas/options-schema.json4
-rw-r--r--ext/js/app/frontend.js8
-rw-r--r--ext/js/app/theme-controller.js14
-rw-r--r--ext/js/display/display.js14
-rw-r--r--ext/js/display/query-parser.js3
-rw-r--r--ext/js/language/text-scanner.js7
-rw-r--r--ext/js/pages/action-popup-main.js2
-rw-r--r--ext/js/pages/info-main.js1
-rw-r--r--ext/js/pages/quick-start-guide-main.js1
-rw-r--r--ext/js/pages/settings/popup-preview-frame.js2
-rw-r--r--ext/js/pages/settings/settings-display-controller.js15
-rw-r--r--ext/settings.html1
-rw-r--r--ext/welcome.html1
-rw-r--r--types/ext/display.d.ts2
-rw-r--r--types/ext/query-parser.d.ts1
-rw-r--r--types/ext/text-scanner.d.ts1
17 files changed, 60 insertions, 23 deletions
diff --git a/ext/css/popup-preview.css b/ext/css/popup-preview.css
index a72edc65..48a1a091 100644
--- a/ext/css/popup-preview.css
+++ b/ext/css/popup-preview.css
@@ -26,6 +26,7 @@
--animation-duration: 0s;
--example-text-color: #333333;
+ --background-color: #f8f9fa;
}
:root[data-loaded=true] {
--animation-duration: 0.25s;
@@ -33,15 +34,16 @@
:root[data-theme=dark] {
--example-text-color: #d4d4d4;
+ --background-color: #1e1e1e;
}
html {
transition: background-color var(--animation-duration) linear 0s, color var(--animation-duration) linear 0s;
- background-color: rgba(255, 255, 255, 0);
+ background-color: var(--background-color);
}
html.dark {
- background-color: #1e1e1e;
+ background-color: var(--background-color);
}
html,
body {
diff --git a/ext/data/schemas/options-schema.json b/ext/data/schemas/options-schema.json
index f4748e69..dc230620 100644
--- a/ext/data/schemas/options-schema.json
+++ b/ext/data/schemas/options-schema.json
@@ -225,8 +225,8 @@
},
"popupTheme": {
"type": "string",
- "enum": ["light", "dark", "browser"],
- "default": "browser"
+ "enum": ["light", "dark", "browser", "site"],
+ "default": "site"
},
"popupOuterTheme": {
"type": "string",
diff --git a/ext/js/app/frontend.js b/ext/js/app/frontend.js
index 71b8d6ef..8ac27979 100644
--- a/ext/js/app/frontend.js
+++ b/ext/js/app/frontend.js
@@ -387,14 +387,14 @@ export class Frontend {
/**
* @param {import('text-scanner').EventArgument<'searchSuccess'>} details
*/
- _onSearchSuccess({type, dictionaryEntries, sentence, inputInfo: {eventType, detail: inputInfoDetail}, textSource, optionsContext, detail}) {
+ _onSearchSuccess({type, dictionaryEntries, sentence, inputInfo: {eventType, detail: inputInfoDetail}, textSource, optionsContext, detail, pageTheme}) {
this._stopClearSelectionDelayed();
let focus = (eventType === 'mouseMove');
if (typeof inputInfoDetail === 'object' && inputInfoDetail !== null) {
const focus2 = inputInfoDetail.focus;
if (typeof focus2 === 'boolean') { focus = focus2; }
}
- this._showContent(textSource, focus, dictionaryEntries, type, sentence, detail !== null ? detail.documentTitle : null, optionsContext);
+ this._showContent(textSource, focus, dictionaryEntries, type, sentence, detail !== null ? detail.documentTitle : null, optionsContext, pageTheme);
}
/** */
@@ -716,8 +716,9 @@ export class Frontend {
* @param {?import('display').HistoryStateSentence} sentence
* @param {?string} documentTitle
* @param {import('settings').OptionsContext} optionsContext
+ * @param {'dark' | 'light'} pageTheme
*/
- _showContent(textSource, focus, dictionaryEntries, type, sentence, documentTitle, optionsContext) {
+ _showContent(textSource, focus, dictionaryEntries, type, sentence, documentTitle, optionsContext, pageTheme) {
const query = textSource.text();
const {url} = optionsContext;
/** @type {import('display').HistoryState} */
@@ -725,6 +726,7 @@ export class Frontend {
focusEntry: 0,
optionsContext,
url,
+ pageTheme,
};
if (sentence !== null) { detailsState.sentence = sentence; }
if (documentTitle !== null) { detailsState.documentTitle = documentTitle; }
diff --git a/ext/js/app/theme-controller.js b/ext/js/app/theme-controller.js
index c12f1113..44ff723b 100644
--- a/ext/js/app/theme-controller.js
+++ b/ext/js/app/theme-controller.js
@@ -27,14 +27,16 @@ export class ThemeController {
constructor(element) {
/** @type {?HTMLElement} */
this._element = element;
- /** @type {'light'|'dark'|'browser'} */
- this._theme = 'light';
/** @type {'light'|'dark'|'browser'|'site'} */
- this._outerTheme = 'light';
+ this._theme = 'site';
+ /** @type {'light'|'dark'|'browser'|'site'} */
+ this._outerTheme = 'site';
/** @type {?('dark'|'light')} */
this._siteTheme = null;
/** @type {'dark'|'light'} */
this._browserTheme = 'light';
+ /** @type {boolean} */
+ this.siteOverride = false;
}
/**
@@ -55,7 +57,7 @@ export class ThemeController {
/**
* Gets the main theme for the content.
- * @type {'light'|'dark'|'browser'}
+ * @type {'light'|'dark'|'browser'|'site'}
*/
get theme() {
return this._theme;
@@ -63,7 +65,7 @@ export class ThemeController {
/**
* Sets the main theme for the content.
- * @param {'light'|'dark'|'browser'} value The theme value to assign.
+ * @param {'light'|'dark'|'browser'|'site'} value The theme value to assign.
*/
set theme(value) {
this._theme = value;
@@ -171,7 +173,7 @@ export class ThemeController {
*/
_resolveThemeValue(theme, computedSiteTheme) {
switch (theme) {
- case 'site': return computedSiteTheme;
+ case 'site': return this.siteOverride ? this._browserTheme : computedSiteTheme;
case 'browser': return this._browserTheme;
default: return theme;
}
diff --git a/ext/js/display/display.js b/ext/js/display/display.js
index e9fdfd9f..386f456b 100644
--- a/ext/js/display/display.js
+++ b/ext/js/display/display.js
@@ -304,7 +304,6 @@ export class Display extends EventDispatcher {
/** */
async prepare() {
// Theme
- this._themeController.siteTheme = 'light';
this._themeController.prepare();
// State setup
@@ -488,6 +487,10 @@ export class Display extends EventDispatcher {
this._history.pushState(state, content, url);
break;
}
+
+ if (this._options) {
+ this._setTheme(this._options);
+ }
}
/**
@@ -1149,8 +1152,16 @@ export class Display extends EventDispatcher {
_setTheme(options) {
const {general} = options;
const {popupTheme} = general;
+ try {
+ // eslint-disable-next-line no-underscore-dangle
+ const pageTheme = this._history._current.state?.pageTheme;
+ this._themeController.siteTheme = pageTheme ?? null;
+ } catch (e) {
+ log.error(e);
+ }
this._themeController.theme = popupTheme;
this._themeController.outerTheme = general.popupOuterTheme;
+ this._themeController.siteOverride = this._pageType === 'search';
this._themeController.updateTheme();
this.setCustomCss(general.customPopupCss);
}
@@ -1933,6 +1944,7 @@ export class Display extends EventDispatcher {
url,
sentence: sentence !== null ? sentence : void 0,
documentTitle,
+ pageTheme: 'light',
},
content: {
dictionaryEntries: dictionaryEntries !== null ? dictionaryEntries : void 0,
diff --git a/ext/js/display/query-parser.js b/ext/js/display/query-parser.js
index c53208ca..344383fb 100644
--- a/ext/js/display/query-parser.js
+++ b/ext/js/display/query-parser.js
@@ -155,7 +155,7 @@ export class QueryParser extends EventDispatcher {
/**
* @param {import('text-scanner').EventArgument<'searchSuccess'>} details
*/
- _onSearchSuccess({type, dictionaryEntries, sentence, inputInfo, textSource, optionsContext}) {
+ _onSearchSuccess({type, dictionaryEntries, sentence, inputInfo, textSource, optionsContext, pageTheme}) {
this.trigger('searched', {
textScanner: this._textScanner,
type,
@@ -165,6 +165,7 @@ export class QueryParser extends EventDispatcher {
textSource,
optionsContext,
sentenceOffset: this._getSentenceOffset(textSource),
+ pageTheme: pageTheme,
});
}
diff --git a/ext/js/language/text-scanner.js b/ext/js/language/text-scanner.js
index fdc33400..249a2eda 100644
--- a/ext/js/language/text-scanner.js
+++ b/ext/js/language/text-scanner.js
@@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+import {ThemeController} from '../app/theme-controller.js';
import {EventDispatcher} from '../core/event-dispatcher.js';
import {EventListenerCollection} from '../core/event-listener-collection.js';
import {log} from '../core/log.js';
@@ -478,6 +479,11 @@ export class TextScanner extends EventDispatcher {
this.setCurrentTextSource(textSource);
this._selectionRestoreInfo = selectionRestoreInfo;
+ /** @type {ThemeController} */
+ this._themeController = new ThemeController(document.documentElement);
+ this._themeController.prepare();
+ const pageTheme = this._themeController.computeSiteTheme();
+
this.trigger('searchSuccess', {
type,
dictionaryEntries,
@@ -486,6 +492,7 @@ export class TextScanner extends EventDispatcher {
textSource,
optionsContext,
detail,
+ pageTheme,
});
} else {
this._triggerSearchEmpty(inputInfo);
diff --git a/ext/js/pages/action-popup-main.js b/ext/js/pages/action-popup-main.js
index ce29bcf1..4137d5c3 100644
--- a/ext/js/pages/action-popup-main.js
+++ b/ext/js/pages/action-popup-main.js
@@ -37,7 +37,6 @@ class DisplayController {
/** */
async prepare() {
- this._themeController.siteTheme = 'light';
this._themeController.prepare();
const manifest = chrome.runtime.getManifest();
@@ -209,6 +208,7 @@ class DisplayController {
void this._updatePermissionsWarnings(options);
this._themeController.theme = options.general.popupTheme;
+ this._themeController.siteOverride = true;
this._themeController.updateTheme();
}
diff --git a/ext/js/pages/info-main.js b/ext/js/pages/info-main.js
index f431239f..079a8c3a 100644
--- a/ext/js/pages/info-main.js
+++ b/ext/js/pages/info-main.js
@@ -163,6 +163,7 @@ await Application.main(true, async (application) => {
const primaryProfile = (profileCurrent >= 0 && profileCurrent < profiles.length) ? profiles[profileCurrent] : null;
if (primaryProfile !== null) {
themeController.theme = primaryProfile.options.general.popupTheme;
+ themeController.siteOverride = true;
themeController.updateTheme();
}
diff --git a/ext/js/pages/quick-start-guide-main.js b/ext/js/pages/quick-start-guide-main.js
index 41644f51..6a3cd39b 100644
--- a/ext/js/pages/quick-start-guide-main.js
+++ b/ext/js/pages/quick-start-guide-main.js
@@ -30,6 +30,7 @@ await Application.main(true, async (application) => {
const primaryProfile = (profileCurrent >= 0 && profileCurrent < profiles.length) ? profiles[profileCurrent] : null;
if (primaryProfile !== null) {
themeController.theme = primaryProfile.options.general.popupTheme;
+ themeController.siteOverride = true;
themeController.updateTheme();
}
});
diff --git a/ext/js/pages/settings/popup-preview-frame.js b/ext/js/pages/settings/popup-preview-frame.js
index 7abcfe2a..dc00d091 100644
--- a/ext/js/pages/settings/popup-preview-frame.js
+++ b/ext/js/pages/settings/popup-preview-frame.js
@@ -77,7 +77,6 @@ export class PopupPreviewFrame {
async prepare() {
window.addEventListener('message', this._onMessage.bind(this), false);
- this._themeController.siteTheme = 'light';
this._themeController.prepare();
// Setup events
@@ -141,6 +140,7 @@ export class PopupPreviewFrame {
options.general.popupVerticalTextPosition = 'before';
options.scanning.selectText = false;
this._themeController.theme = options.general.popupTheme;
+ this._themeController.siteOverride = true;
this._themeController.updateTheme();
return options;
}
diff --git a/ext/js/pages/settings/settings-display-controller.js b/ext/js/pages/settings/settings-display-controller.js
index 49f7192c..e179b835 100644
--- a/ext/js/pages/settings/settings-display-controller.js
+++ b/ext/js/pages/settings/settings-display-controller.js
@@ -42,11 +42,12 @@ export class SettingsDisplayController {
this._onMenuButtonClickBind = this._onMenuButtonClick.bind(this);
/** @type {ThemeController} */
this._themeController = new ThemeController(document.documentElement);
+ /** @type {HTMLSelectElement | null}*/
+ this._themeDropdown = document.querySelector('[data-setting="general.popupTheme"]');
}
/** */
prepare() {
- this._themeController.siteTheme = 'light';
this._themeController.prepare();
void this._updateTheme();
@@ -92,16 +93,18 @@ export class SettingsDisplayController {
window.addEventListener('popstate', this._onPopState.bind(this), false);
this._updateScrollTarget();
- const themeDropdown = document.querySelector('[data-setting="general.popupTheme"]');
- if (themeDropdown) {
- themeDropdown.addEventListener('change', this._updateTheme.bind(this), false);
+ if (this._themeDropdown) {
+ this._themeDropdown.addEventListener('change', this._updateTheme.bind(this), false);
}
}
/** */
async _updateTheme() {
- const options = await this._settingsController.getOptions();
- this._themeController.theme = options.general.popupTheme;
+ const theme = this._themeDropdown?.value;
+ if (theme === 'site' || theme === 'light' || theme === 'dark' || theme === 'browser') {
+ this._themeController.theme = theme;
+ }
+ this._themeController.siteOverride = true;
this._themeController.updateTheme();
}
diff --git a/ext/settings.html b/ext/settings.html
index 35545f7a..20472292 100644
--- a/ext/settings.html
+++ b/ext/settings.html
@@ -680,6 +680,7 @@
<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="site">Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="browser">Browser</option>
diff --git a/ext/welcome.html b/ext/welcome.html
index 0aab51e9..44212026 100644
--- a/ext/welcome.html
+++ b/ext/welcome.html
@@ -132,6 +132,7 @@
</div>
<div class="settings-item-right">
<select data-setting="general.popupTheme" class="short-width">
+ <option value="site">Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="browser">Browser</option>
diff --git a/types/ext/display.d.ts b/types/ext/display.d.ts
index 7f4d8966..3aba304e 100644
--- a/types/ext/display.d.ts
+++ b/types/ext/display.d.ts
@@ -95,6 +95,8 @@ export type HistoryState = {
url?: string;
/** The originating document title of the content. */
documentTitle?: string;
+ /** Computed theme of the page */
+ pageTheme?: 'dark' | 'light';
};
/**
diff --git a/types/ext/query-parser.d.ts b/types/ext/query-parser.d.ts
index b1064973..aa90e3a4 100644
--- a/types/ext/query-parser.d.ts
+++ b/types/ext/query-parser.d.ts
@@ -33,6 +33,7 @@ export type Events = {
textSource: TextSource;
optionsContext: OptionsContext;
sentenceOffset: number | null;
+ pageTheme: 'dark' | 'light';
};
};
diff --git a/types/ext/text-scanner.d.ts b/types/ext/text-scanner.d.ts
index 21ca8f24..4277d49a 100644
--- a/types/ext/text-scanner.d.ts
+++ b/types/ext/text-scanner.d.ts
@@ -122,6 +122,7 @@ export type Events = {
textSource: TextSource.TextSource;
optionsContext: Settings.OptionsContext;
detail: SearchResultDetail;
+ pageTheme: 'dark' | 'light';
};
searchEmpty: {
inputInfo: InputInfo;