Banner style is no longer a generated file, public page gets appearance as CSS variables. Fixes #13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+36
-2
@@ -741,14 +741,29 @@ pub struct Appearance {
|
||||
id: i32,
|
||||
pub banner: Option<String>,
|
||||
pub text: Option<String>,
|
||||
pub title: Option<String>,
|
||||
pub css_name: Option<String>
|
||||
pub title: Option<String>
|
||||
}
|
||||
|
||||
impl Appearance {
|
||||
pub fn id(&self) -> i32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
/// CSS variables for the banner of the public page, used as its `style` attribute.
|
||||
/// The styles themselves are in `assets/css/public.css`.
|
||||
pub fn banner_style(&self) -> String {
|
||||
match &self.banner {
|
||||
Some(banner) if is_css_safe_file_name(banner) => format!("--rz-banner-image: url('/data/{}')", banner),
|
||||
_ => String::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The value is put into a `style` attribute, so it must not be able to end the `url()` or the declaration
|
||||
fn is_css_safe_file_name(name: &str) -> bool {
|
||||
!name.is_empty()
|
||||
&& !name.starts_with('.')
|
||||
&& name.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_' || c == '.')
|
||||
}
|
||||
|
||||
pub fn validate_closing_time(time: &ClosingTime) -> Result<(), ValidationError> {
|
||||
@@ -1272,6 +1287,25 @@ mod tests {
|
||||
assert_eq!(SlotType::Day.to_string(), "Day");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_style_sets_image_variable() {
|
||||
let appearance = Appearance { banner: Some("my-banner_1.jpg".to_string()), ..Default::default() };
|
||||
assert_eq!(appearance.banner_style(), "--rz-banner-image: url('/data/my-banner_1.jpg')");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_style_is_empty_without_banner() {
|
||||
assert_eq!(Appearance::default().banner_style(), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_style_ignores_unsafe_file_names() {
|
||||
for name in ["", "a'); color: red; x: url('.jpg", "a b.jpg", "../config.toml", "a/b.jpg", "a\\b.jpg", "a\"b.jpg", "a;b.jpg", "a)b.jpg", ".hidden"] {
|
||||
let appearance = Appearance { banner: Some(name.to_string()), ..Default::default() };
|
||||
assert_eq!(appearance.banner_style(), "", "name: {:?}", name);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enum_defaults() {
|
||||
assert_eq!(ReservationState::default(), ReservationState::New);
|
||||
|
||||
Reference in New Issue
Block a user