summaryrefslogtreecommitdiff
path: root/ext/fg/js
diff options
context:
space:
mode:
authorAlex Yatskov <FooSoft@users.noreply.github.com>2019-10-13 08:58:40 -0700
committerGitHub <noreply@github.com>2019-10-13 08:58:40 -0700
commit320af99b7676a37157e2d7207756dd502e6be608 (patch)
tree5c28a1abba2693b22b1f3f7932f69cabcbaa453c /ext/fg/js
parent537d2ef532aa7b7498de13ab039bd23f28d32714 (diff)
parent57db18c31b117591982795c930cc9f07efc28641 (diff)
Merge pull request #253 from toasted-nutbread/style-editor
Popup style preview + themes
Diffstat (limited to 'ext/fg/js')
-rw-r--r--ext/fg/js/float.js21
-rw-r--r--ext/fg/js/frontend.js8
-rw-r--r--ext/fg/js/popup-proxy-host.js6
-rw-r--r--ext/fg/js/popup-proxy.js5
-rw-r--r--ext/fg/js/popup.js46
5 files changed, 63 insertions, 23 deletions
diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js
index 5164cd8f..4b3cd848 100644
--- a/ext/fg/js/float.js
+++ b/ext/fg/js/float.js
@@ -21,7 +21,6 @@ class DisplayFloat extends Display {
constructor() {
super(document.querySelector('#spinner'), document.querySelector('#definitions'));
this.autoPlayAudioTimer = null;
- this.styleNode = null;
this.optionsContext = {
depth: 0,
@@ -101,11 +100,6 @@ class DisplayFloat extends Display {
async initialize(options, popupInfo, url, childrenSupported) {
await super.initialize(options);
- const css = options.general.customPopupCss;
- if (css) {
- this.setStyle(css);
- }
-
const {id, depth, parentFrameId} = popupInfo;
this.optionsContext.depth = depth;
this.optionsContext.url = url;
@@ -114,20 +108,6 @@ class DisplayFloat extends Display {
popupNestedInitialize(id, depth, parentFrameId, url);
}
}
-
- setStyle(css) {
- const parent = document.head;
-
- if (this.styleNode === null) {
- this.styleNode = document.createElement('style');
- }
-
- this.styleNode.textContent = css;
-
- if (this.styleNode.parentNode !== parent) {
- parent.appendChild(this.styleNode);
- }
- }
}
DisplayFloat.onKeyDownHandlers = {
@@ -145,6 +125,7 @@ DisplayFloat.messageHandlers = {
kanjiShow: (self, {definitions, context}) => self.kanjiShow(definitions, context),
clearAutoPlayTimer: (self) => self.clearAutoPlayTimer(),
orphaned: (self) => self.onOrphaned(),
+ setCustomCss: (self, {css}) => self.setCustomCss(css),
initialize: (self, {options, popupInfo, url, childrenSupported}) => self.initialize(options, popupInfo, url, childrenSupported)
};
diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js
index 52a23889..3ddeae78 100644
--- a/ext/fg/js/frontend.js
+++ b/ext/fg/js/frontend.js
@@ -44,6 +44,8 @@ class Frontend {
this.isPreparedPromiseResolve = null;
this.isPreparedPromise = new Promise((resolve) => { this.isPreparedPromiseResolve = resolve; });
+
+ this.lastShowPromise = Promise.resolve();
}
static create() {
@@ -331,7 +333,7 @@ class Frontend {
} catch (e) {
if (window.yomichan_orphaned) {
if (textSource && this.options.scanning.modifier !== 'none') {
- this.popup.showOrphaned(
+ this.lastShowPromise = this.popup.showOrphaned(
textSource.getRect(),
textSource.getWritingMode()
);
@@ -369,7 +371,7 @@ class Frontend {
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
const url = window.location.href;
- this.popup.termsShow(
+ this.lastShowPromise = this.popup.termsShow(
textSource.getRect(),
textSource.getWritingMode(),
definitions,
@@ -399,7 +401,7 @@ class Frontend {
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
const url = window.location.href;
- this.popup.kanjiShow(
+ this.lastShowPromise = this.popup.kanjiShow(
textSource.getRect(),
textSource.getWritingMode(),
definitions,
diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js
index 74a5153a..bb323f64 100644
--- a/ext/fg/js/popup-proxy-host.js
+++ b/ext/fg/js/popup-proxy-host.js
@@ -45,6 +45,7 @@ class PopupProxyHost {
containsPoint: ({id, x, y}) => this.containsPoint(id, x, y),
termsShow: ({id, elementRect, writingMode, definitions, context}) => this.termsShow(id, elementRect, writingMode, definitions, context),
kanjiShow: ({id, elementRect, writingMode, definitions, context}) => this.kanjiShow(id, elementRect, writingMode, definitions, context),
+ setCustomCss: ({id, css}) => this.setCustomCss(id, css),
clearAutoPlayTimer: ({id}) => this.clearAutoPlayTimer(id)
});
}
@@ -126,6 +127,11 @@ class PopupProxyHost {
return await popup.kanjiShow(elementRect, writingMode, definitions, context);
}
+ async setCustomCss(id, css) {
+ const popup = this.getPopup(id);
+ return popup.setCustomCss(css);
+ }
+
async clearAutoPlayTimer(id) {
const popup = this.getPopup(id);
return popup.clearAutoPlayTimer();
diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js
index e8d6bc98..6ea94b6a 100644
--- a/ext/fg/js/popup-proxy.js
+++ b/ext/fg/js/popup-proxy.js
@@ -88,6 +88,11 @@ class PopupProxy {
return await this.invokeHostApi('kanjiShow', {id, elementRect, writingMode, definitions, context});
}
+ async setCustomCss(css) {
+ const id = await this.getPopupId();
+ return await this.invokeHostApi('setCustomCss', {id, css});
+ }
+
async clearAutoPlayTimer() {
if (this.id === null) {
return;
diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js
index f36bb436..ef4cdb67 100644
--- a/ext/fg/js/popup.js
+++ b/ext/fg/js/popup.js
@@ -85,6 +85,7 @@ class Popup {
async setOptions(options) {
this.options = options;
+ this.updateTheme();
}
async show(elementRect, writingMode) {
@@ -269,6 +270,47 @@ class Popup {
}
}
+ updateTheme() {
+ this.container.dataset.yomichanTheme = this.getTheme(this.options.general.popupOuterTheme);
+ }
+
+ getTheme(themeName) {
+ if (themeName === 'auto') {
+ const color = [255, 255, 255];
+ Popup.addColor(color, Popup.getColorInfo(window.getComputedStyle(document.documentElement).backgroundColor));
+ Popup.addColor(color, Popup.getColorInfo(window.getComputedStyle(document.body).backgroundColor));
+ const dark = (color[0] < 128 && color[1] < 128 && color[2] < 128);
+ themeName = dark ? 'dark' : 'default';
+ }
+
+ return themeName;
+ }
+
+ static addColor(target, color) {
+ if (color === null) { return; }
+
+ const a = color[3];
+ if (a <= 0.0) { return; }
+
+ const aInv = 1.0 - a;
+ for (let i = 0; i < 3; ++i) {
+ target[i] = target[i] * aInv + color[i] * a;
+ }
+ }
+
+ static getColorInfo(cssColor) {
+ const m = /^\s*rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d\.]+)\s*)?\)\s*$/.exec(cssColor);
+ if (m === null) { return null; }
+
+ const m4 = m[4];
+ return [
+ Number.parseInt(m[1], 10),
+ Number.parseInt(m[2], 10),
+ Number.parseInt(m[3], 10),
+ m4 ? Math.max(0.0, Math.min(1.0, Number.parseFloat(m4))) : 1.0
+ ];
+ }
+
async containsPoint(x, y) {
for (let popup = this; popup !== null && popup.isVisible(); popup = popup.child) {
const rect = popup.container.getBoundingClientRect();
@@ -291,6 +333,10 @@ class Popup {
this.invokeApi('kanjiShow', {definitions, context});
}
+ async setCustomCss(css) {
+ this.invokeApi('setCustomCss', {css});
+ }
+
clearAutoPlayTimer() {
if (this.isInjected) {
this.invokeApi('clearAutoPlayTimer');