Skip to content

Commit

Permalink
Merge pull request #549 from jaytaph/css3-styling-2
Browse files Browse the repository at this point in the history
Css3 styling 2
  • Loading branch information
jaytaph authored Aug 13, 2024
2 parents 02c241e + fc34214 commit bbf7119
Show file tree
Hide file tree
Showing 43 changed files with 23,453 additions and 1,060 deletions.
189 changes: 147 additions & 42 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "gosub_engine"
version = "0.1.0"
edition = "2021"
rust-version = "1.73"
rust-version = "1.79"
authors = ["Gosub Community <[email protected]>"]
description = "An HTML5 browser engine written in Rust."
license = "MIT"
Expand Down Expand Up @@ -47,6 +47,8 @@ clap = { version = "4.5.13", features = ["derive"] }
simple_logger = "5.0.0"
cookie = { version = "0.18.1", features = ["secure", "private"] }
url = "2.5.2"
nom = "7.1.3"
nom-trace = "0.2.1"

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
Expand Down
1 change: 1 addition & 0 deletions crates/gosub_css3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ lazy_static = "1.5"
log = "0.4.22"
simple_logger = "5.0.0"
anyhow = { version = "1.0.86", features = [] }
colors-transform = "0.2.11"
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use colors_transform::Color;
use colors_transform::{AlphaColor, Hsl, Rgb};
use lazy_static::lazy_static;
use std::convert::From;
use std::fmt::Debug;
use std::str::FromStr;

use colors_transform::Color;
use colors_transform::{AlphaColor, Hsl, Rgb};
use lazy_static::lazy_static;

// Values for this table is taken from https://www.w3.org/TR/CSS21/propidx.html
// Probably not the complete list, but it will do for now

Expand Down Expand Up @@ -51,6 +52,11 @@ impl From<&str> for RgbColor {
if value.is_empty() {
return RgbColor::default();
}
if value == "currentcolor" {
// @todo: implement currentcolor
return RgbColor::default();
}

if value.starts_with('#') {
return parse_hex(value);
}
Expand Down Expand Up @@ -86,6 +92,7 @@ impl From<&str> for RgbColor {
return RgbColor::new(rgb.get_red(), rgb.get_green(), rgb.get_blue(), 255.0);
}
if value.starts_with("hsla(") {
// @TODO: hsla() does not work properly
// HSLA function
let hsl = Hsl::from_str(value);
if hsl.is_err() {
Expand All @@ -105,7 +112,7 @@ impl From<&str> for RgbColor {
}

fn get_hex_color_from_name(color_name: &str) -> Option<&str> {
for entry in crate::css_colors::CSS_COLORNAMES.iter() {
for entry in crate::colors::CSS_COLORNAMES.iter() {
if entry.name == color_name {
return Some(entry.value);
}
Expand Down Expand Up @@ -778,6 +785,69 @@ lazy_static! {
];
}

pub fn is_system_color(name: &str) -> bool {
for entry in CSS_SYSTEM_COLOR_NAMES.iter() {
if entry == &name {
return true;
}
}
false
}

pub fn is_named_color(name: &str) -> bool {
for entry in CSS_COLORNAMES.iter() {
if entry.name == name {
return true;
}
}
false
}

pub const CSS_SYSTEM_COLOR_NAMES: [&str; 42] = [
"AccentColor",
"AccentColorText",
"ActiveText",
"ButtonBorder",
"ButtonFace",
"ButtonText",
"Canvas",
"CanvasText",
"Field",
"FieldText",
"GrayText",
"Highlight",
"HighlightText",
"LinkText",
"Mark",
"MarkText",
"SelectedItem",
"SelectedItemText",
"VisitedText",
"ActiveBorder",
"ActiveCaption",
"AppWorkspace",
"Background",
"ButtonHighlight",
"ButtonShadow",
"CaptionText",
"InactiveBorder",
"InactiveCaption",
"InactiveCaptionText",
"InfoBackground",
"InfoText",
"Menu",
"MenuText",
"Scrollbar",
"ThreeDDarkShadow",
"ThreeDFace",
"ThreeDHighlight",
"ThreeDLightShadow",
"ThreeDShadow",
"Window",
"WindowFrame",
"WindowText",
];

#[cfg(test)]
mod tests {
#[test]
Expand Down Expand Up @@ -905,4 +975,36 @@ mod tests {
assert_eq!(color.b, 0x99 as f32);
assert_eq!(color.a, 255.0);
}

#[test]
fn rgb_func_colors() {
let color = super::RgbColor::from("rgb(10, 20, 30)");
assert_eq!(color.r, 10.0);
assert_eq!(color.g, 20.0);
assert_eq!(color.b, 30.0);
assert_eq!(color.a, 255.0);

// invalid color
let color = super::RgbColor::from("rgb(10)");
assert_eq!(color.r, 0.0);
assert_eq!(color.g, 0.0);
assert_eq!(color.b, 0.0);
assert_eq!(color.a, 255.0);
}

#[test]
fn hsl_func_colors() {
let color = super::RgbColor::from("hsl(10, 20%, 30%)");
assert_eq!(color.r, 91.8);
assert_eq!(color.g, 66.3);
assert_eq!(color.b, 61.2);
assert_eq!(color.a, 255.0);

// invalid color
let color = super::RgbColor::from("hsl(10)");
assert_eq!(color.r, 0.0);
assert_eq!(color.g, 0.0);
assert_eq!(color.b, 0.0);
assert_eq!(color.a, 255.0);
}
}
110 changes: 105 additions & 5 deletions crates/gosub_css3/src/convert/ast_converter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::node::{Node as CssNode, NodeType};
use crate::stylesheet::{
CssDeclaration, CssOrigin, CssRule, CssSelector, CssSelectorPart, CssSelectorType,
CssStylesheet, MatcherType,
CssStylesheet, CssValue, MatcherType,
};
use anyhow::anyhow;
use gosub_shared::types::Result;
Expand Down Expand Up @@ -56,7 +56,6 @@ in css:
vs
h3 { color: rebeccapurple; }
h4 { color: rebeccapurple; }
*/

/// Converts a CSS AST to a CSS stylesheet structure
Expand Down Expand Up @@ -92,7 +91,6 @@ pub fn convert_ast_to_stylesheet(
}

let mut selector = CssSelector { parts: vec![] };

for node in node.as_selector_list().iter() {
if !node.is_selector() {
continue;
Expand Down Expand Up @@ -170,10 +168,23 @@ pub fn convert_ast_to_stylesheet(
continue;
}

let (property, value, important) = declaration.as_declaration();
let (property, nodes, important) = declaration.as_declaration();

// Convert the nodes into CSS Values
let mut css_values = vec![];
for node in nodes.iter() {
if let Ok(value) = CssValue::parse_ast_node(node) {
css_values.push(value);
}
}

if css_values.is_empty() {
continue;
}

rule.declarations.push(CssDeclaration {
property: property.clone(),
value: value[0].to_string(),
value: css_values.to_vec(),
important: *important,
});
}
Expand All @@ -183,3 +194,92 @@ pub fn convert_ast_to_stylesheet(
}
Ok(sheet)
}

#[cfg(test)]
mod tests {
use super::*;
use crate::parser_config::ParserConfig;
use crate::Css3;

#[test]
fn convert_font_family() {
let ast = Css3::parse(
r#"
body {
border: 1px solid black;
color: #ffffff;
background-color: #121212;
font-family: "Arial", sans-serif;
margin: 0;
padding: 0;
}
"#,
ParserConfig::default(),
)
.unwrap();

let tree = convert_ast_to_stylesheet(&ast, CssOrigin::UserAgent, "test.css").unwrap();

dbg!(&tree);
}

#[test]
fn convert_test() {
let ast = Css3::parse(
r#"
h1 { color: red; }
h3, h4 { border: 1px solid black; }
"#,
ParserConfig::default(),
)
.unwrap();

let tree = convert_ast_to_stylesheet(&ast, CssOrigin::UserAgent, "test.css").unwrap();

assert_eq!(
tree.rules
.first()
.unwrap()
.declarations
.first()
.unwrap()
.property,
"color"
);
assert_eq!(
tree.rules
.first()
.unwrap()
.declarations
.first()
.unwrap()
.value,
vec![CssValue::String("red".into())]
);

assert_eq!(
tree.rules
.get(1)
.unwrap()
.declarations
.first()
.unwrap()
.property,
"border"
);
assert_eq!(
tree.rules
.get(1)
.unwrap()
.declarations
.first()
.unwrap()
.value,
vec![
CssValue::Unit(1.0, "px".into()),
CssValue::String("solid".into()),
CssValue::String("black".into())
]
);
}
}
1 change: 1 addition & 0 deletions crates/gosub_css3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::tokenizer::Tokenizer;
use gosub_shared::byte_stream::{ByteStream, Encoding, Location};
use gosub_shared::{timing_start, timing_stop};

pub mod colors;
pub mod convert;
mod node;
pub mod parser;
Expand Down
Loading

0 comments on commit bbf7119

Please sign in to comment.