Update handling of custom css (#965)

"Default" css is no longer required to be part of the request
when updating styles.

Closes #934
main
João 2023-04-13 22:19:36 +02:00 committed by GitHub
parent 9d9022ed99
commit bf6c2505b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 8 deletions

View File

@ -1,4 +1,5 @@
from inspect import Attribute from inspect import Attribute
from typing import Optional
from app.utils.misc import read_config_bool from app.utils.misc import read_config_bool
from flask import current_app from flask import current_app
import os import os
@ -8,6 +9,31 @@ import pickle
from cryptography.fernet import Fernet from cryptography.fernet import Fernet
import hashlib import hashlib
import brotli import brotli
import logging
import cssutils
from cssutils.css.cssstylesheet import CSSStyleSheet
from cssutils.css.cssstylerule import CSSStyleRule
# removes warnings from cssutils
cssutils.log.setLevel(logging.CRITICAL)
def get_rule_for_selector(stylesheet: CSSStyleSheet,
selector: str) -> Optional[CSSStyleRule]:
"""Search for a rule that matches a given selector in a stylesheet.
Args:
stylesheet (CSSStyleSheet) -- the stylesheet to search
selector (str) -- the selector to search for
Returns:
Optional[CSSStyleRule] -- the rule that matches the selector or None
"""
for rule in stylesheet.cssRules:
if hasattr(rule, "selectorText") and selector == rule.selectorText:
return rule
return None
class Config: class Config:
@ -16,10 +42,8 @@ class Config:
self.url = os.getenv('WHOOGLE_CONFIG_URL', '') self.url = os.getenv('WHOOGLE_CONFIG_URL', '')
self.lang_search = os.getenv('WHOOGLE_CONFIG_SEARCH_LANGUAGE', '') self.lang_search = os.getenv('WHOOGLE_CONFIG_SEARCH_LANGUAGE', '')
self.lang_interface = os.getenv('WHOOGLE_CONFIG_LANGUAGE', '') self.lang_interface = os.getenv('WHOOGLE_CONFIG_LANGUAGE', '')
self.style = os.getenv( self.style_modified = os.getenv(
'WHOOGLE_CONFIG_STYLE', 'WHOOGLE_CONFIG_STYLE', '')
open(os.path.join(app_config['STATIC_FOLDER'],
'css/variables.css')).read())
self.block = os.getenv('WHOOGLE_CONFIG_BLOCK', '') self.block = os.getenv('WHOOGLE_CONFIG_BLOCK', '')
self.block_title = os.getenv('WHOOGLE_CONFIG_BLOCK_TITLE', '') self.block_title = os.getenv('WHOOGLE_CONFIG_BLOCK_TITLE', '')
self.block_url = os.getenv('WHOOGLE_CONFIG_BLOCK_URL', '') self.block_url = os.getenv('WHOOGLE_CONFIG_BLOCK_URL', '')
@ -88,6 +112,33 @@ class Config:
if not name.startswith("__") if not name.startswith("__")
and (type(attr) is bool or type(attr) is str)} and (type(attr) is bool or type(attr) is str)}
@property
def style(self) -> str:
"""Returns the default style updated with specified modifications.
Returns:
str -- the new style
"""
style_sheet = cssutils.parseString(
open(os.path.join(current_app.config['STATIC_FOLDER'],
'css/variables.css')).read()
)
modified_sheet = cssutils.parseString(self.style_modified)
for rule in modified_sheet:
rule_default = get_rule_for_selector(style_sheet,
rule.selectorText)
# if modified rule is in default stylesheet, update it
if rule_default is not None:
# TODO: update this in a smarter way to handle :root better
# for now if we change a varialbe in :root all other default
# variables need to be also present
rule_default.style = rule.style
# else add the new rule to the default stylesheet
else:
style_sheet.add(rule)
return str(style_sheet.cssText, 'utf-8')
@property @property
def preferences(self) -> str: def preferences(self) -> str:
# if encryption key is not set will uncheck preferences encryption # if encryption key is not set will uncheck preferences encryption

View File

@ -243,15 +243,13 @@
{{ translation['config-css'] }}: {{ translation['config-css'] }}:
</a> </a>
<textarea <textarea
name="style" name="style_modified"
id="config-style" id="config-style"
autocapitalize="off" autocapitalize="off"
autocomplete="off" autocomplete="off"
spellcheck="false" spellcheck="false"
autocorrect="off" autocorrect="off"
value=""> value="">{{ config.style_modified.replace('\t', '') }}</textarea>
{{ config.style.replace('\t', '') }}
</textarea>
</div> </div>
<div class="config-div config-div-pref-url"> <div class="config-div config-div-pref-url">
<label for="config-pref-encryption">{{ translation['config-pref-encryption'] }}: </label> <label for="config-pref-encryption">{{ translation['config-pref-encryption'] }}: </label>