1
//! The `style` element.
2

            
3
use markup5ever::{expanded_name, local_name, namespace_url, ns};
4

            
5
use crate::element::{set_attribute, ElementTrait};
6
use crate::error::*;
7
use crate::session::Session;
8
use crate::xml::Attributes;
9

            
10
/// Represents the syntax used in the `<style>` node.
11
///
12
/// Currently only "text/css" is supported.
13
///
14
/// <https://www.w3.org/TR/SVG11/styling.html#StyleElementTypeAttribute>
15
/// <https://www.w3.org/TR/SVG11/styling.html#ContentStyleTypeAttribute>
16
85
#[derive(Copy, Clone, Default, PartialEq, Debug)]
17
pub enum StyleType {
18
    #[default]
19
    TextCss,
20
}
21

            
22
impl StyleType {
23
34
    fn parse(value: &str) -> Result<StyleType, ValueErrorKind> {
24
        // https://html.spec.whatwg.org/multipage/semantics.html#the-style-element
25
        //
26
        // 4. If element's type attribute is present and its value is
27
        // neither the empty string nor an ASCII case-insensitive
28
        // match for "text/css", then return.
29

            
30
34
        if value.eq_ignore_ascii_case("text/css") {
31
32
            Ok(StyleType::TextCss)
32
        } else {
33
2
            Err(ValueErrorKind::parse_error(
34
                "invalid value for type attribute in style element",
35
            ))
36
        }
37
34
    }
38
}
39

            
40
/// Represents a `<style>` node.
41
///
42
/// It does not render itself, and just holds CSS stylesheet information for the rest of
43
/// the code to use.
44
84
#[derive(Default)]
45
pub struct Style {
46
42
    type_: StyleType,
47
}
48

            
49
impl Style {
50
42
    pub fn style_type(&self) -> StyleType {
51
        self.type_
52
42
    }
53
}
54

            
55
impl ElementTrait for Style {
56
42
    fn set_attributes(&mut self, attrs: &Attributes, session: &Session) {
57
73
        for (attr, value) in attrs.iter() {
58
31
            if attr.expanded() == expanded_name!("", "type") {
59
31
                set_attribute(
60
                    &mut self.type_,
61
31
                    StyleType::parse(value).attribute(attr),
62
                    session,
63
                );
64
            }
65
31
        }
66
42
    }
67
}
68

            
69
#[cfg(test)]
70
mod tests {
71
    use super::*;
72

            
73
    #[test]
74
2
    fn parses_style_type() {
75
1
        assert_eq!(StyleType::parse("text/css").unwrap(), StyleType::TextCss);
76
2
    }
77

            
78
    #[test]
79
2
    fn invalid_style_type_yields_error() {
80
1
        assert!(StyleType::parse("").is_err());
81
1
        assert!(StyleType::parse("some-other-stylesheet-language").is_err());
82
2
    }
83
}