From 9832c6191a951697e4b43db29185e3cb03d7a9db Mon Sep 17 00:00:00 2001 From: Ben Busby Date: Wed, 17 Mar 2021 16:48:47 -0400 Subject: [PATCH] Add custom CSS field to config This allows users to set/customize an instance's theme and appearance to their liking. The config CSS field is prepopulated with all default CSS variable values to allow quick editing. Note that this can be somewhat of a "footgun" if someone updates the CSS to hide all fields/search/etc. Should probably add some sort of bandaid "admin" feature for public instances to employ until the whole cookie/session issue is investigated further. --- app/models/config.py | 7 ++ app/routes.py | 4 +- app/static/css/dark-theme.css | 110 +++++++++++++++++++++++----- app/static/css/light-theme.css | 130 +++++++++++++++++++++++++++++++++ app/static/css/main.css | 73 +++++++++++------- app/static/css/search-dark.css | 40 ---------- app/static/css/search.css | 39 ---------- app/static/css/variables.css | 24 ++++++ app/static/img/whoogle.svg | 1 + app/static/js/controller.js | 40 ---------- app/templates/display.html | 9 +-- app/templates/header.html | 16 ++-- app/templates/index.html | 85 +++++++++++++-------- 13 files changed, 372 insertions(+), 206 deletions(-) create mode 100644 app/static/css/light-theme.css delete mode 100644 app/static/css/search-dark.css delete mode 100644 app/static/css/search.css create mode 100644 app/static/css/variables.css create mode 100644 app/static/img/whoogle.svg diff --git a/app/models/config.py b/app/models/config.py index 3916be2..756af29 100644 --- a/app/models/config.py +++ b/app/models/config.py @@ -1,8 +1,15 @@ +from flask import current_app +import os + + class Config: def __init__(self, **kwargs): + app_config = current_app.config self.url = '' self.lang_search = '' self.lang_interface = '' + self.style = open(os.path.join(app_config['STATIC_FOLDER'], + 'css/variables.css')).read() self.ctry = '' self.safe = False self.dark = False diff --git a/app/routes.py b/app/routes.py index b084f71..10336ed 100644 --- a/app/routes.py +++ b/app/routes.py @@ -233,12 +233,12 @@ def search(): 'display.html', query=urlparse.unquote(query), search_type=search_util.search_type, - dark_mode=g.user_config.dark, + config=g.user_config, response=response, version_number=app.config['VERSION_NUMBER'], search_header=(render_template( 'header.html', - dark_mode=g.user_config.dark, + config=g.user_config, query=urlparse.unquote(query), search_type=search_util.search_type, mobile=g.user_request.mobile) diff --git a/app/static/css/dark-theme.css b/app/static/css/dark-theme.css index 4bd6af1..637f1c2 100644 --- a/app/static/css/dark-theme.css +++ b/app/static/css/dark-theme.css @@ -1,13 +1,17 @@ html { - background-color: #222 !important; + background: var(--whoogle-dark-background) !important; } body { - background-color: #222 !important; + background: var(--whoogle-dark-background) !important; } div { - color: #fff !important; + color: var(--whoogle-dark-text) !important; +} + +label { + color: var(--whoogle-dark-contrast-text) !important; } li a { @@ -15,43 +19,113 @@ li a { } li { - color: #fff !important; + color: var(--whoogle-dark-text) !important; +} + +textarea { + background: var(--whoogle-dark-background) !important; + color: var(--whoogle-dark-text) !important; } a:visited h3 div { - color: #bbbbff !important; + color: var(--whoogle-result-visited) !important; } a:link h3 div { - color: #4b8eea !important; + color: var(--whoogle-result-title) !important; } a:link div { - color: #aaffaa !important; + color: var(--whoogle-result-url) !important; } div span { - color: #bbb !important; + color: var(--whoogle-secondary-text) !important; } input { - background-color: #111 !important; - color: #fff !important; + background-color: var(--whoogle-dark-background) !important; + color: var(--whoogle-dark-text) !important; } -#search-bar { - color: #fff !important; - background-color: #222 !important; +select { + background: var(--whoogle-dark-background) !important; + color: var(--whoogle-dark-text) !important; } .search-container { - background-color: #222 !important; + background-color: var(--whoogle-dark-background) !important; } -.ZINbbc{ - background-color: #1a1a1a !important; +.ZINbbc { + background-color: var(--whoogle-dark-result-bg) !important; } -.bRsWnc{ - background-color: #1a1a1a !important; +.bRsWnc { + background-color: var(--whoogle-dark-result-bg) !important; +} + +#search-bar { + border: 3px solid var(--whoogle-dark-accent) !important; + color: var(--whoogle-dark-text) !important; +} + +#search-bar:focus { + color: var(--whoogle-dark-text) !important; +} + +#search-submit { + border: 1px solid var(--whoogle-dark-accent) !important; + background: var(--whoogle-dark-accent) !important; + color: var(--whoogle-dark-background) !important; +} + +.info-text { + color: var(--whoogle-dark-contrast-text) !important; + opacity: 75%; +} + +.collapsible { + color: var(--whoogle-dark-accent) !important; +} + +.collapsible:after { + color: var(--whoogle-dark-accent) !important; +} + +.active { + background-color: var(--whoogle-dark-accent) !important; + color: var(--whoogle-dark-contrast-text) !important; +} + +.content { + background-color: var(--whoogle-dark-accent) !important; + color: var(--whoogle-contrast-text) !important; +} + +.active:after { + color: var(--whoogle-contrast-text); +} + +#gh-link { + color: var(--whoogle-dark-accent); +} + +.autocomplete-items { + border: 1px solid #685e79; +} + +.autocomplete-items div { + color: #fff; + background-color: #222; + border-bottom: 1px solid #242424; +} + +.autocomplete-items div:hover { + background-color: #404040; +} + +.autocomplete-active { + background-color: var(--whoogle-dark-accent) !important; + color: var(--whoogle-dark-background) !important; } diff --git a/app/static/css/light-theme.css b/app/static/css/light-theme.css new file mode 100644 index 0000000..27741a2 --- /dev/null +++ b/app/static/css/light-theme.css @@ -0,0 +1,130 @@ +html { + background: var(--whoogle-background) !important; +} + +body { + background: var(--whoogle-background) !important; +} + +div { + color: var(--whoogle-text) !important; +} + +label { + color: var(--whoogle-contrast-text) !important; +} + +li a { + color: #4b8eaa !important; +} + +li { + color: var(--whoogle-text) !important; +} + +textarea { + background: var(--whoogle-background) !important; + color: var(--whoogle-text) !important; +} + +select { + background: var(--whoogle-background) !important; + color: var(--whoogle-text) !important; +} + +.ZINbbc { + background-color: var(--whoogle-result-bg) !important; +} + +.bRsWnc { + background-color: var(--whoogle-result-bg) !important; +} + +a:visited h3 div { + color: var(--whoogle-result-visited) !important; +} + +a:link h3 div { + color: var(--whoogle-result-title) !important; +} + +a:link div { + color: var(--whoogle-result-url) !important; +} + +div span { + color: var(--whoogle-secondary-text) !important; +} + +input { + background-color: var(--whoogle-background) !important; + color: var(--whoogle-text) !important; +} + +#search-bar { + color: var(--whoogle-text) !important; + background-color: var(--whoogle-background) !important; +} + +.home-search { + border: 3px solid var(--whoogle-accent) !important; +} + +.search-container { + background-color: var(--whoogle-background) !important; +} + +#search-submit { + border: 1px solid var(--whoogle-accent) !important; + background: var(--whoogle-accent) !important; + color: var(--whoogle-background) !important; +} + +.info-text { + color: var(--whoogle-contrast-text) !important; + opacity: 75%; +} + +.collapsible { + color: var(--whoogle-accent) !important; +} + +.collapsible:after { + color: var(--whoogle-accent) !important; +} + +.active { + background-color: var(--whoogle-accent) !important; + color: var(--whoogle-contrast-text) !important; +} + +.content { + background-color: var(--whoogle-accent) !important; + color: var(--whoogle-contrast-text) !important; +} + +.active:after { + color: var(--whoogle-contrast-text); +} + +#gh-link { + color: var(--whoogle-accent); +} + +.autocomplete-items { + border: 1px solid #d4d4d4; +} + +.autocomplete-items div { + background-color: #fff; + border-bottom: 1px solid #d4d4d4; +} + +.autocomplete-items div:hover { + background-color: #e9e9e9; +} + +.autocomplete-active { + background-color: var(--whoogle-accent) !important; + color: var(--whoogle-background) !important; +} diff --git a/app/static/css/main.css b/app/static/css/main.css index 5b35bf6..937812a 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -10,6 +10,7 @@ body { } .search-container { + background: transparent !important; width: 80%; position: absolute; top: 50%; @@ -26,29 +27,21 @@ body { } #search-bar { + background: transparent !important; width: 100%; - border: 3px solid #685e79; padding: 5px; height: 40px; outline: none; font-size: 24px; - color: #685e79; border-radius: 10px 10px 0 0; max-width: 600px; background: rgba(0, 0, 0, 0); } -#search-bar:focus { - color: #685e79; -} - #search-submit { width: 100%; height: 40px; - border: 1px solid #685e79; - background: #685e79 !important; text-align: center; - color: #fff; cursor: pointer; font-size: 20px; align-content: center; @@ -70,7 +63,6 @@ button::-moz-focus-inner { .collapsible { outline: 0; background-color: rgba(0, 0, 0, 0); - color: #685e79; cursor: pointer; padding: 18px; width: 100%; @@ -81,14 +73,8 @@ button::-moz-focus-inner { border-radius: 10px 10px 0 0; } -.active { - background-color: #685e79; - color: white; -} - .collapsible:after { content: '\002B'; - color: #685e79; font-weight: bold; float: right; margin-left: 5px; @@ -96,7 +82,6 @@ button::-moz-focus-inner { .active:after { content: "\2212"; - color: white; } .content { @@ -104,8 +89,6 @@ button::-moz-focus-inner { max-height: 0; overflow: hidden; transition: max-height 0.2s ease-out; - background-color: #685e79; - color: white; border-radius: 0 0 10px 10px; } @@ -113,12 +96,6 @@ button::-moz-focus-inner { padding-bottom: 20px; } -.ua-span { - color: white; - -webkit-box-decoration-break: clone; - box-decoration-break: clone; -} - .hidden { display: none; } @@ -135,3 +112,49 @@ footer { font-style: italic; font-size: 12px; } + +#config-style { + resize: none; + overflow-y: scroll; + width: 100%; + height: 100px; +} + +.whoogle-logo { + display: none; +} + +.whoogle-svg { + width: 80%; + display: block; + margin: auto; + padding-bottom: 10px; +} + +.autocomplete { + position: relative; + display: inline-block; + width: 100%; +} + +.autocomplete-items { + position: absolute; + border-bottom: none; + border-top: none; + z-index: 99; + + /*position the autocomplete items to be the same width as the container:*/ + top: 100%; + left: 0; + right: 0; +} + +.autocomplete-items div { + padding: 10px; + cursor: pointer; +} + +details summary { + padding: 10px; + font-weight: bold; +} diff --git a/app/static/css/search-dark.css b/app/static/css/search-dark.css deleted file mode 100644 index efd923e..0000000 --- a/app/static/css/search-dark.css +++ /dev/null @@ -1,40 +0,0 @@ -.autocomplete { - position: relative; - display: inline-block; - width: 100%; -} - -.autocomplete-items { - position: absolute; - border: 1px solid #685e79; - border-bottom: none; - border-top: none; - z-index: 99; - - /*position the autocomplete items to be the same width as the container:*/ - top: 100%; - left: 0; - right: 0; -} - -.autocomplete-items div { - padding: 10px; - cursor: pointer; - color: #fff; - background-color: #222; - border-bottom: 1px solid #242424; -} - -.autocomplete-items div:hover { - background-color: #404040; -} - -.autocomplete-active { - background-color: #685e79 !important; - color: #ffffff; -} - -details summary { - padding: 10px; - font-weight: bold; -} diff --git a/app/static/css/search.css b/app/static/css/search.css deleted file mode 100644 index 155cfcf..0000000 --- a/app/static/css/search.css +++ /dev/null @@ -1,39 +0,0 @@ -.autocomplete { - position: relative; - display: inline-block; - width: 100%; -} - -.autocomplete-items { - position: absolute; - border: 1px solid #d4d4d4; - border-bottom: none; - border-top: none; - z-index: 99; - - /*position the autocomplete items to be the same width as the container:*/ - top: 100%; - left: 0; - right: 0; -} - -.autocomplete-items div { - padding: 10px; - cursor: pointer; - background-color: #fff; - border-bottom: 1px solid #d4d4d4; -} - -.autocomplete-items div:hover { - background-color: #e9e9e9; -} - -.autocomplete-active { - background-color: #685e79 !important; - color: #ffffff; -} - -details summary { - padding: 10px; - font-weight: bold; -} diff --git a/app/static/css/variables.css b/app/static/css/variables.css new file mode 100644 index 0000000..efb6d3a --- /dev/null +++ b/app/static/css/variables.css @@ -0,0 +1,24 @@ +/* Colors */ +:root { + /* LIGHT THEME COLORS */ + --whoogle-background: #fff; + --whoogle-accent: #685e79; + --whoogle-text: #000; + --whoogle-contrast-text: #fff; + --whoogle-secondary-text: #70757a; + --whoogle-result-bg: #fff; + --whoogle-result-title: #1967d2; + --whoogle-result-url: #0d652d; + --whoogle-result-visited: #4b11a8; + + /* DARK THEME COLORS */ + --whoogle-dark-background: #222; + --whoogle-dark-accent: #685e79; + --whoogle-dark-text: #fff; + --whoogle-dark-contrast-text: #000; + --whoogle-dark-secondary-text: #bbb; + --whoogle-dark-result-bg: #000; + --whoogle-dark-result-title: #1967d2; + --whoogle-dark-result-url: #4b11a8; + --whoogle-dark-result-visited: #bbbbff; +} diff --git a/app/static/img/whoogle.svg b/app/static/img/whoogle.svg new file mode 100644 index 0000000..41a783e --- /dev/null +++ b/app/static/img/whoogle.svg @@ -0,0 +1 @@ + diff --git a/app/static/js/controller.js b/app/static/js/controller.js index 3ab8ca7..8399220 100644 --- a/app/static/js/controller.js +++ b/app/static/js/controller.js @@ -1,14 +1,3 @@ -// Whoogle configurations that use boolean values and checkboxes -CONFIG_BOOLS = [ - "nojs", "dark", "safe", "alts", "new_tab", "get_only", "tor" -]; - -// Whoogle configurations that use string values and input fields -CONFIG_STRS = [ - "near", "url" -]; - - const setupSearchLayout = () => { // Setup search field const searchBar = document.getElementById("search-bar"); @@ -28,33 +17,6 @@ const setupSearchLayout = () => { }); }; -const fillConfigValues = () => { - // Request existing config info - let xhrGET = new XMLHttpRequest(); - xhrGET.open("GET", "config"); - xhrGET.onload = function() { - if (xhrGET.readyState === 4 && xhrGET.status !== 200) { - alert("Error loading Whoogle config"); - return; - } - - // Allow for updating/saving config values - let configSettings = JSON.parse(xhrGET.responseText); - - CONFIG_STRS.forEach(function(item) { - let configElement = document.getElementById("config-" + item.replace("_", "-")); - configElement.value = configSettings[item] ? configSettings[item] : ""; - }); - - CONFIG_BOOLS.forEach(function(item) { - let configElement = document.getElementById("config-" + item.replace("_", "-")); - configElement.checked = !!configSettings[item]; - }); - }; - - xhrGET.send(); -}; - const setupConfigLayout = () => { // Setup whoogle config const collapsible = document.getElementById("config-collapsible"); @@ -69,8 +31,6 @@ const setupConfigLayout = () => { content.classList.toggle("open"); }); - - fillConfigValues(); }; const loadConfig = event => { diff --git a/app/templates/display.html b/app/templates/display.html index 30eba0a..9913f55 100644 --- a/app/templates/display.html +++ b/app/templates/display.html @@ -5,11 +5,10 @@ - + - {% if dark_mode %} - - {% endif %} + + {{ query }} - Whoogle Search @@ -17,7 +16,7 @@ {{ response|safe }}