From cd4a3bf83a71aa9e35b2adee751f53e8f6abf098 Mon Sep 17 00:00:00 2001
From: lionel-rowe <lionel.rowe@gmail.com>
Date: Mon, 6 Dec 2021 21:20:01 -0600
Subject: [PATCH] Add option for custom tone colors

---
 background.js   |  3 ++-
 content.js      |  9 +++++++++
 css/content.css | 22 ++++++++++++++++++++++
 js/options.js   | 32 ++++++++++++++++++++++++++++++++
 options.html    | 13 +++++++++++++
 5 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/background.js b/background.js
index c88e2b5..ab3fa52 100644
--- a/background.js
+++ b/background.js
@@ -64,7 +64,8 @@ let zhongwenOptions = window.zhongwenOptions = {
     zhuyin: localStorage['zhuyin'] || 'no',
     grammar: localStorage['grammar'] || 'yes',
     simpTrad: localStorage['simpTrad'] || 'classic',
-    toneColorScheme: localStorage['toneColorScheme'] || 'standard'
+    toneColorScheme: localStorage['toneColorScheme'] || 'standard',
+    customToneColorScheme: JSON.parse(localStorage['customToneColorScheme'] || '{}')
 };
 
 function activateExtension(tabId, showHelp) {
diff --git a/content.js b/content.js
index 50974c3..5c271ba 100644
--- a/content.js
+++ b/content.js
@@ -628,6 +628,15 @@ function showPopup(html, elem, x, y, looseWidth) {
     popup.style.maxWidth = (looseWidth ? '' : '600px');
     popup.className = `background-${config.css} tonecolor-${config.toneColorScheme}`;
 
+    if (config.toneColorScheme === 'custom') {
+        for (let n = 1; n <= 5; ++n) {
+            popup.style.setProperty(
+                `--zhongwen-tonecolor-${n}`,
+                config.customToneColorScheme?.[`tone${n}`] ?? '#000000'
+            );
+        }
+    }
+
     $(popup).html(html);
 
     if (elem) {
diff --git a/css/content.css b/css/content.css
index 8ce41c2..23c5916 100644
--- a/css/content.css
+++ b/css/content.css
@@ -221,3 +221,25 @@
 #zhongwen-window.tonecolor-hanping .tone5 {
   color: #a0a0a0;
 }
+
+
+/* Custom Tone Colors */
+#zhongwen-window.tonecolor-custom .tone1 {
+  color: var(--zhongwen-tonecolor-1);
+}
+
+#zhongwen-window.tonecolor-custom .tone2 {
+  color: var(--zhongwen-tonecolor-2);
+}
+
+#zhongwen-window.tonecolor-custom .tone3 {
+  color: var(--zhongwen-tonecolor-3);
+}
+
+#zhongwen-window.tonecolor-custom .tone4 {
+  color: var(--zhongwen-tonecolor-4);
+}
+
+#zhongwen-window.tonecolor-custom .tone5 {
+  color: var(--zhongwen-tonecolor-5);
+}
diff --git a/js/options.js b/js/options.js
index 2f56c5d..0857231 100644
--- a/js/options.js
+++ b/js/options.js
@@ -19,6 +19,11 @@ function loadVals() {
         document.querySelector(`input[name="toneColors"][value="${toneColorScheme}"]`).checked = true;
     }
 
+    const customToneColorScheme = JSON.parse(localStorage['customToneColorScheme'] || '{}');
+    Object.entries(customToneColorScheme).forEach(([key, val]) => {
+        document.querySelector(`input[id="${key}"]`).value = val;
+    });
+
     const fontSize = localStorage['fontSize'] || 'small';
     document.querySelector(`input[name="fontSize"][value="${fontSize}"]`).checked = true;
 
@@ -52,6 +57,14 @@ function setToneColorScheme(toneColorScheme) {
     }
 }
 
+function updateCustomToneColorScheme() {
+    const toneColorEls = document.querySelectorAll('input[name="customToneColors"]');
+    const toneColors = Object.fromEntries([...toneColorEls]
+        .map(el => [el.id, el.value]));
+
+    setJsonOption('customToneColorScheme', toneColors);
+}
+
 function setOption(option, value) {
     localStorage[option] = value;
     chrome.extension.getBackgroundPage().zhongwenOptions[option] = value;
@@ -62,6 +75,11 @@ function setBooleanOption(option, value) {
     setOption(option, yesNo);
 }
 
+function setJsonOption(option, value) {
+    localStorage[option] = JSON.stringify(value);
+    chrome.extension.getBackgroundPage().zhongwenOptions[option] = value;
+}
+
 window.addEventListener('load', () => {
 
     document.querySelectorAll('input[name="popupColor"]').forEach((input) => {
@@ -74,6 +92,10 @@ window.addEventListener('load', () => {
             () => setToneColorScheme(input.getAttribute('value')));
     });
 
+    document.querySelectorAll('input[name="toneColors"], input[name="customToneColors"]').forEach((input) => {
+        input.addEventListener('change', updateCustomToneColorScheme);
+    });
+
     document.querySelectorAll('input[name="fontSize"]').forEach((input) => {
         input.addEventListener('change',
             () => setOption('fontSize', input.getAttribute('value')));
@@ -103,3 +125,13 @@ window.addEventListener('load', () => {
 
 loadVals();
 
+const toggleCustomToneColorOptions = () => {
+    document.querySelector('#toneColorsCustomOptions').hidden =
+        !document.querySelector('#toneColorsCustom').checked;
+}
+
+toggleCustomToneColorOptions();
+
+document.querySelectorAll('input[name="toneColors"]').forEach((input) => {
+    input.addEventListener('change', toggleCustomToneColorOptions);
+});
diff --git a/options.html b/options.html
index 648895f..3464bb7 100644
--- a/options.html
+++ b/options.html
@@ -64,6 +64,19 @@ <h2 class="mb-3">Appearance of the Pop-up Window</h2>
                     href="https://hanpingchinese.com/" target="_blank">Hanping</a> color
                 scheme.</label>
         </div>
+        <div class="custom-control custom-radio">
+            <input type="radio" id="toneColorsCustom" name="toneColors"
+                   class="custom-control-input" value="custom">
+            <label class="custom-control-label" for="toneColorsCustom">Use a custom color
+                scheme.</label>
+        </div>
+        <div id="toneColorsCustomOptions" class="custom-control" hidden>
+            <label for="tone1">Tone 1</label> <input name="customToneColors" type="color" id="tone1" value="#000000">
+            <label for="tone2">Tone 2</label> <input name="customToneColors" type="color" id="tone2" value="#000000">
+            <label for="tone3">Tone 3</label> <input name="customToneColors" type="color" id="tone3" value="#000000">
+            <label for="tone4">Tone 4</label> <input name="customToneColors" type="color" id="tone4" value="#000000">
+            <label for="tone5">Tone 5</label> <input name="customToneColors" type="color" id="tone5" value="#000000">
+        </div>
         <div class="custom-control custom-radio">
             <input type="radio" id="toneColorsNone" name="toneColors" class="custom-control-input"
                    value="none">