diff --git a/README.md b/README.md index 4561c78..fcc7417 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,21 @@ To install: * An install page should pop up automatically. -* Click the `Enable Dark Theme` option in the top right corner while browsing any Wiki pages. +## Settings + +To open the Settings modal: + +* Click the `Settings` option in the top right corner while browsing any Wiki pages. + +Within, you can choose how Wikipedia pages look to you. + +Select a single light or dark theme, or sync with your system and automatically switch between light and dark themes. + +Moreover, you can choose your own link color and contrast value. + +Try to adjust these values and find the Wikipedia theme that looks best for you. + +If you change your mind, you can always go back to default settings by clicking the `Restore defaults` button. ## Supported Pages @@ -50,6 +64,8 @@ Wikipedia Dark Theme supports the following pages: ## Screenshots -| **Before** | **After** | -| -------------------------------------------- | ------------------------------------------------ | -| ![A Wikipedia page](/screenshots/dark_theme_disabled.png) | ![A dark Wikipedia page](/screenshots/dark_theme_enabled.png) | +| **Light Theme** | **Dark Theme** | +| :------------------------------------------------------: | :-------------------------------------------------------------------------: | +| ![A Wikipedia page](/screenshots/dark_theme_disabled.png)| ![A dark Wikipedia page](/screenshots/dark_theme_enabled.png) | +| **Settings Menu** | **Custom Link Color** | +| ![Settings menu](/screenshots/settings_menu.png) | ![Wikipedia page with custom link color](/screenshots/custom_link_color.png)| diff --git a/Wikipedia Dark Theme.user.js b/Wikipedia Dark Theme.user.js index fdc06ce..5b363ae 100644 --- a/Wikipedia Dark Theme.user.js +++ b/Wikipedia Dark Theme.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Wikipedia Dark Theme // @author Shangru Li -// @version 1.32 +// @version 1.40 // @match *://*.wikipedia.org/* // @match *://*.mediawiki.org/* // @match *://*.wikimedia.org/* @@ -36,6 +36,7 @@ const DEFAULT_CONTRAST_VALUE = 8; const DEFAULT_FOREGROUND_COLOR = "rgb(238, 255, 255)"; const DEFAULT_BACKGROUND_COLOR = "rgb(35, 35, 35)"; +const DEFAULT_LINK_COLOR = "rgb(249, 186, 82)"; //############################################___One_Could_Alter_If_Desired___########################################## //############################################___Global_Variables___#################################################### @@ -69,7 +70,7 @@ const EXCLUDE_SRC_TAG = [ "px-applications-graphics", "px-pody_candidate", "px-potd-logo", "px-pd-icon", "px-dialog-warning", "px-checked_copyright_icon", "px-valued_image_seal", "px-cscr-former", "px-red_x", "px-crystal_clear_app_kedit", "px-people_icon", - "kit_shorts", "kit_socks", "wikipedia-logo", "phacility_phabricator_logo", + "kit_shorts", "kit_socks", "wikipedia-logo-v2", "phacility_phabricator_logo", "wikimedia_cloud_services_logo", "lingualibre-logo", "le_dico_des_ados_small_logo", "vikidia_v_vectorised", "sciences_humaines", "science-symbol", "history2", "vote3_final", "p_religion_world", "tecno-rueda", "notification-icon", @@ -100,7 +101,7 @@ const INVERT_SRC_TAG = [ "font_awesome_5_solid_tree", "font_awesome_5_solid_globe", "font_awesome_5_solid_futbol", "font_awesome_5_solid_hourglass", "font_awesome_5_solid_users", "font_awesome_5_solid_palette", "font_awesome_5_solid_rocket", "font_awesome_5_solid_bong", "vlad1Trezub", "font_awesome_5_solid_flag", - "font_awesome_5_solid_university", "wikipedia_wordmark" + "font_awesome_5_solid_university", "wikipedia_wordmark", "wikipedia-logo-textonly" ]; //############################################___Controller___########################################################## @@ -116,11 +117,11 @@ const INVERT_SRC_TAG = [ applyDarkTheme(); } else if ('complete' === document.readyState) { setPageVisibility("visible"); - addToggleScriptButton(); + initSettingElements(); invertSpecialElements(); } } else if ('complete' === document.readyState) { - addToggleScriptButton(); + initSettingElements(); } })(); @@ -136,8 +137,8 @@ function applyDarkTheme() { // General idea is to put all elements on a wikipedia page to an array `allElements` // traverse through this array and reverse the color of each element accordingly // running time o(n), where n is the number of elements on a page - document.querySelectorAll('*').forEach(function(element) { - try { + document.querySelectorAll('*').forEach(function (element) { + try { if (!isSpecialElement(element)) { changeForegroundColor(element); changeBackgroundColor(element); @@ -149,11 +150,15 @@ function applyDarkTheme() { } function isSpecialElement(e) { - if (elementIsImage(e)) { + if (elementIsWikiLogo(e)) { + invertImage(e, 90); + return true; + } else if (elementIsImage(e)) { changeImageIfOnLists(e); return true; - } else if (elementIsWikiLogo(e)) { - invertImage(e, 90); + } else if (elementIsHyperlink(e)) { + e.style.color = GM_getValue("linkColor"); + changeBackgroundColor(e); return true; } else if (elementIsKeyboardKey(e)) { e.style.foregroundColor = DEFAULT_BACKGROUND_COLOR; @@ -213,6 +218,10 @@ function invertImage(img, percent) { img.style.filter = "invert(" + percent + "%)"; } +function elementIsHyperlink(e) { + return e.tagName.toLowerCase() === 'a'; +} + function elementIsWikiLogo(e) { return e.className.toLowerCase().includes("mw-wiki-logo"); } @@ -264,7 +273,7 @@ function changeForegroundColor(e) { if (colorIsRGB(foregroundColor)) { foregroundColor = splitToRGB(foregroundColor); foregroundColor = inverseRBGColor(foregroundColor); - foregroundColor = increaseRGBToMatchContrastValue(foregroundColor, DEFAULT_BACKGROUND_COLOR_RGB, DEFAULT_CONTRAST_VALUE, 30); + foregroundColor = increaseRGBToMatchContrastValue(foregroundColor, DEFAULT_BACKGROUND_COLOR_RGB, GM_getValue("contrastValue"), 30); e.style.color = RGBArrayToString(foregroundColor); } else { e.style.color = DEFAULT_FOREGROUND_COLOR; @@ -280,7 +289,7 @@ function changeBackgroundColor(e) { if (RGBTooDark(backgroundColor)) { backgroundColor = addValueToRGB(backgroundColor, 30); } - backgroundColor = decreaseRGBToMatchContrastValue(backgroundColor, DEFAULT_BACKGROUND_COLOR_RGB, DEFAULT_CONTRAST_VALUE, -30); + backgroundColor = decreaseRGBToMatchContrastValue(backgroundColor, DEFAULT_BACKGROUND_COLOR_RGB, GM_getValue("contrastValue"), -30); e.style.backgroundColor = RGBArrayToString(backgroundColor); } else if (backgroundColor !== "rgba(0, 0, 0, 0)" || elementToChangeBackground(e)) { e.style.backgroundColor = DEFAULT_BACKGROUND_COLOR; @@ -356,6 +365,10 @@ function RGBArrayToString(rgb) { return 'rgb(' + rgb[0] + ', ' + rgb[1] + ', ' + rgb[2] + ')'; } +function RGBToHex(r, g, b) { + return "#" + ((1 << 24) + (Number(r) << 16) + (Number(g) << 8) + Number(b)).toString(16).slice(1); +} + function elementToChangeBackground(e) { return e.id.toLowerCase().includes("mw-head") || e.parentElement.id.includes("ca-"); } @@ -399,21 +412,41 @@ function invertSpecialElements() { } } -//############################################___Toggle_Script_Button___################################################ +//############################################___Init_Elements___####################################################### -function addToggleScriptButton() { - // Create a list that contains toggle script button - let toggleScriptList = document.createElement('li'); - let toggleScriptElement = document.createElement('a'); - toggleScriptElement.id = "toggleScriptElement"; - toggleScriptElement.style.fontWeight = 'bold'; - toggleScriptElement.onclick = function () { - // `GM_setValue()` and `GM_getValue()` are from Tampermonkey API - GM_setValue("scriptEnabled", !GM_getValue("scriptEnabled")); - location.reload(); +function initSettingElements() { + initGMStorage(); + insertSettingsModalStyles(); + createSettingsModal(); + addButtonListeners(); + addSettingsButton(); + updateSettingsModal(); +} + +function initGMStorage(reset = false) { + if (!GM_getValue("linkColor") || reset) { + const split = splitToRGB(DEFAULT_LINK_COLOR); + GM_setValue("linkColor", RGBToHex(split[0], split[1], split[2])); + } + if (!GM_getValue("contrastValue") || reset) { + GM_setValue("contrastValue", DEFAULT_CONTRAST_VALUE); + } +} + +//############################################___Settings_Button___##################################################### + +function addSettingsButton() { + // Create a list that contains settings button + let settingsButtonList = document.createElement("li"); + let settingsButton = document.createElement("a"); + settingsButton.id = "settingsButton"; + settingsButton.style.fontWeight = 'bold'; + settingsButton.onclick = function () { + let settingsModal = document.getElementById("settingsModal") + settingsModal.style.display = "block"; return false; }; - toggleScriptList.appendChild(toggleScriptElement); + settingsButtonList.appendChild(settingsButton); // Getting the login button and logout button const loginLinkElement = document.getElementById("pt-login"); const logoutLinkElement = document.getElementById("pt-logout"); @@ -421,45 +454,365 @@ function addToggleScriptButton() { // Get the parent of either element that is defined let parentList = (loginLinkElement) ? (loginLinkElement.parentElement) : (logoutLinkElement.parentElement); // Adding toggle script button to after the login/logout button - parentList.appendChild(toggleScriptList); - updateToggleScriptButton(); + parentList.appendChild(settingsButtonList); + setSettingsButton(); } -function updateToggleScriptButton() { +function setSettingsButton() { + let settingsButton = document.getElementById("settingsButton"); + let text, title; switch (LOCALE) { case "zh": - if (GM_getValue("scriptEnabled")) { - setToggleScriptButton("关闭黑色主题", "单击来关闭维基百科黑色主题。", "white"); - } else { - setToggleScriptButton("开启黑色主题", "单击来开启维基百科黑色主题。", "black"); - } + text = "设置"; + title = "设置维基百科黑色主题。"; break; case "ja": - if (GM_getValue("scriptEnabled")) { - setToggleScriptButton("ダークテーマを解除する", "ここをクリックしてダークテーマから切り替わる。", "white"); - } else { - setToggleScriptButton("ダークテーマを設定する", "ここをクリックしてダークテーマに切り替わる。", "black"); - } + text = "設定"; + title = "ウィキペディアダークテーマを設定します。"; break; case "fr": - if (GM_getValue("scriptEnabled")) { - setToggleScriptButton("Fermer le thème noir", "Cliquer pour fermer le thème noir.", "white"); - } else { - setToggleScriptButton("Ouvrir le thème noir", "Cliquer pour ouvrir le thème noir.", "black"); - } + text = "Les paramètres"; + title = "Modifiez les paramètres de Wikipédia Dark Theme."; break; default: - if (GM_getValue("scriptEnabled")) { - setToggleScriptButton("Disable Dark Theme", "Click to disable Wikipedia Dark Theme.", "white"); - } else { - setToggleScriptButton("Enable Dark Theme", "Click to enable Wikipedia Dark Theme.", "black"); - } + text = "Settings"; + title = "Change settings for Wikipedia Dark Theme."; + } + settingsButton.text = text; + settingsButton.title = title; + settingsButton.style.color = GM_getValue("scriptEnabled") ? "white" : "black"; +} + +//############################################___Settings_Modal___###################################################### + +function createSettingsModal() { + let settingsModal = ` +