[librsvg: 1/3] Add a user agent stylesheet



commit a904d1785b8cbafc5a3887130d5bd98b4d3dc1cc
Author: Paolo Borelli <pborelli gnome org>
Date:   Fri Mar 20 14:48:51 2020 +0100

    Add a user agent stylesheet
    
    Add a stylesheet with the user agent defaults present in the
    specification and remove the special cases in SpecifiedValues.
    
    Note: this breaks a couple of reftests because we do not
    currently handle correctly the priority of presentation
    attributes and user agent css.

 Makefile.am                      |  1 +
 rsvg_internals/src/css.rs        | 16 ++++++++++++----
 rsvg_internals/src/document.rs   | 12 +++++++++---
 rsvg_internals/src/element.rs    | 38 ++++++++++---------------------------
 rsvg_internals/src/properties.rs | 11 -----------
 rsvg_internals/src/ua.css        | 41 ++++++++++++++++++++++++++++++++++++++++
 6 files changed, 73 insertions(+), 46 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index e1a92eab..bf2c1888 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -130,6 +130,7 @@ RUST_EXTRA =                                                \
        rsvg_internals/benches/lighting.rs              \
        rsvg_internals/benches/pixel_iterators.rs       \
        rsvg_internals/benches/srgb.rs                  \
+       rsvg_internals/src/ua.css                       \
        $(NULL)
 
 if DEBUG_RELEASE
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index 130e5806..57e74031 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -566,7 +566,6 @@ impl selectors::Element for RsvgElement {
 /// Origin for a stylesheet, per https://www.w3.org/TR/CSS22/cascade.html#cascading-order
 ///
 /// This is used when sorting selector matches according to their origin and specificity.
-#[allow(unused)]
 #[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
 pub enum Origin {
     UserAgent,
@@ -735,7 +734,12 @@ impl Stylesheet {
 }
 
 /// Runs the CSS cascade on the specified tree from all the stylesheets
-pub fn cascade(root: &mut Node, stylesheets: &[Stylesheet], extra: &[Stylesheet]) {
+pub fn cascade(
+    root: &mut Node,
+    ua_stylesheets: &[Stylesheet],
+    author_stylesheets: &[Stylesheet],
+    user_stylesheets: &[Stylesheet],
+) {
     for mut node in root.descendants().filter(|n| n.is_element()) {
         let mut matches = Vec::new();
 
@@ -748,8 +752,12 @@ pub fn cascade(root: &mut Node, stylesheets: &[Stylesheet], extra: &[Stylesheet]
             QuirksMode::NoQuirks,
         );
 
-        for stylesheet in stylesheets.iter().chain(extra.iter()) {
-            stylesheet.get_matches(&node, &mut match_ctx, &mut matches);
+        for s in ua_stylesheets
+            .iter()
+            .chain(author_stylesheets)
+            .chain(user_stylesheets)
+        {
+            s.get_matches(&node, &mut match_ctx, &mut matches);
         }
 
         matches.as_mut_slice().sort();
diff --git a/rsvg_internals/src/document.rs b/rsvg_internals/src/document.rs
index a5d67d76..23a5ccf4 100644
--- a/rsvg_internals/src/document.rs
+++ b/rsvg_internals/src/document.rs
@@ -2,9 +2,11 @@
 
 use gdk_pixbuf::{PixbufLoader, PixbufLoaderExt};
 use markup5ever::QualName;
+use once_cell::sync::Lazy;
 use std::cell::RefCell;
 use std::collections::hash_map::Entry;
 use std::collections::HashMap;
+use std::include_str;
 use std::rc::Rc;
 
 use crate::allowed_url::{AllowedUrl, AllowedUrlError, Fragment};
@@ -20,6 +22,10 @@ use crate::structure::{IntrinsicDimensions, Svg};
 use crate::surface_utils::shared_surface::SharedImageSurface;
 use crate::xml::xml_load_from_possibly_compressed_stream;
 
+static UA_STYLESHEETS: Lazy<Vec<Stylesheet>> = Lazy::new(|| {
+    vec![Stylesheet::from_data(include_str!("ua.css"), None, Origin::UserAgent).unwrap()]
+});
+
 /// A loaded SVG file and its derived data.
 pub struct Document {
     /// Tree of nodes; the root is guaranteed to be an `<svg>` element.
@@ -103,10 +109,10 @@ impl Document {
 
     /// Runs the CSS cascade on the document tree
     ///
-    /// This uses the document's internal stylesheets, plus an extra set of stylesheets
-    /// supplied by the caller.
+    /// This uses the deafault UserAgent stylesheet, the document's internal stylesheets,
+    /// plus an extra set of stylesheets supplied by the caller.
     pub fn cascade(&mut self, extra: &[Stylesheet]) {
-        css::cascade(&mut self.tree, &self.stylesheets, extra);
+        css::cascade(&mut self.tree, &UA_STYLESHEETS, &self.stylesheets, extra);
     }
 }
 
diff --git a/rsvg_internals/src/element.rs b/rsvg_internals/src/element.rs
index 6166c4f0..486d54fa 100644
--- a/rsvg_internals/src/element.rs
+++ b/rsvg_internals/src/element.rs
@@ -372,18 +372,13 @@ impl fmt::Display for Element {
 
 macro_rules! e {
     ($name:ident, $element_type:ident) => {
-        pub fn $name(
-            element_name: &QualName,
-            id: Option<&str>,
-            class: Option<&str>,
-            specified_values: SpecifiedValues,
-        ) -> Element {
+        pub fn $name(element_name: &QualName, id: Option<&str>, class: Option<&str>) -> Element {
             Element {
                 element_type: ElementType::$element_type,
                 element_name: element_name.clone(),
                 id: id.map(str::to_string),
                 class: class.map(str::to_string),
-                specified_values,
+                specified_values: Default::default(),
                 important_styles: Default::default(),
                 transform: Default::default(),
                 result: Ok(()),
@@ -469,20 +464,13 @@ mod creators {
 
 use creators::*;
 
-type ElementCreateFn = fn(
-    element_name: &QualName,
-    id: Option<&str>,
-    class: Option<&str>,
-    specified_values: SpecifiedValues,
-) -> Element;
+type ElementCreateFn =
+    fn(element_name: &QualName, id: Option<&str>, class: Option<&str>) -> Element;
 
-// For now it's just an enum, if some element needs more than one flag
-// we will need something fancier
 #[derive(Copy, Clone, PartialEq)]
 enum ElementCreateFlags {
     Default,
     IgnoreClass,
-    OverflowHidden,
 }
 
 // Lines in comments are elements that we don't support.
@@ -543,17 +531,17 @@ static ELEMENT_CREATORS: Lazy<HashMap<&'static str, (ElementCreateFn, ElementCre
         /* ("glyph",            ), */
         /* ("glyphRef",         ), */
         /* ("hkern",            ), */
-        ("image",               create_image,                 OverflowHidden),
+        ("image",               create_image,                 Default),
         ("line",                create_line,                  Default),
         ("linearGradient",      create_linear_gradient,       Default),
-        ("marker",              create_marker,                OverflowHidden),
+        ("marker",              create_marker,                Default),
         ("mask",                create_mask,                  Default),
         /* ("metadata",         ), */
         /* ("missing-glyph",    ), */
         /* ("mpath",            ), */
         /* ("multiImage",       ), */
         ("path",                create_path,                  Default),
-        ("pattern",             create_pattern,               OverflowHidden),
+        ("pattern",             create_pattern,               Default),
         ("polygon",             create_polygon,               Default),
         ("polyline",            create_polyline,              Default),
         ("radialGradient",      create_radial_gradient,       Default),
@@ -564,9 +552,9 @@ static ELEMENT_CREATORS: Lazy<HashMap<&'static str, (ElementCreateFn, ElementCre
         ("style",               create_style,                 IgnoreClass),
         /* ("subImage",         ), */
         /* ("subImageRef",      ), */
-        ("svg",                 create_svg,                   OverflowHidden),
+        ("svg",                 create_svg,                   Default),
         ("switch",              create_switch,                Default),
-        ("symbol",              create_symbol,                OverflowHidden),
+        ("symbol",              create_symbol,                Default),
         ("text",                create_text,                  Default),
         /* ("textPath",         ), */
         /* ("title",            ), */
@@ -623,15 +611,9 @@ pub fn create_element(name: &QualName, pbag: &PropertyBag) -> Element {
         class = None;
     };
 
-    let specified_values = if flags == ElementCreateFlags::OverflowHidden {
-        SpecifiedValues::with_overflow_hidden()
-    } else {
-        SpecifiedValues::default()
-    };
-
     //    sizes::print_sizes();
 
-    create_fn(name, id, class, specified_values)
+    create_fn(name, id, class)
 }
 
 #[cfg(ignore)]
diff --git a/rsvg_internals/src/properties.rs b/rsvg_internals/src/properties.rs
index f250c263..277705ae 100644
--- a/rsvg_internals/src/properties.rs
+++ b/rsvg_internals/src/properties.rs
@@ -262,17 +262,6 @@ impl Default for SpecifiedValues {
     }
 }
 
-impl SpecifiedValues {
-    pub fn with_overflow_hidden() -> SpecifiedValues {
-        let mut s = SpecifiedValues::default();
-        s.set_parsed_property(&ParsedProperty::Overflow(SpecifiedValue::Specified(
-            Overflow::Hidden,
-        )));
-
-        s
-    }
-}
-
 #[derive(Debug, Default, Clone)]
 pub struct ComputedValues {
     pub baseline_shift: BaselineShift,
diff --git a/rsvg_internals/src/ua.css b/rsvg_internals/src/ua.css
new file mode 100644
index 00000000..3292f8ac
--- /dev/null
+++ b/rsvg_internals/src/ua.css
@@ -0,0 +1,41 @@
+/* See https://www.w3.org/TR/SVG/styling.html#UAStyleSheet
+ *
+ * Commented out rules cannot yet be parsed.
+ */
+
+/*
+@namespace url(http://www.w3.org/2000/svg);
+@namespace xml url(http://www.w3.org/XML/1998/namespace);
+*/
+
+svg:not(:root), image, marker, pattern, symbol { overflow: hidden; }
+
+/*
+*:not(svg),
+*:not(foreignObject) > svg {
+  transform-origin: 0 0;
+}
+
+*[xml|space=preserve] {
+  text-space-collapse: preserve-spaces;
+}
+*/
+
+defs,
+clipPath, mask, marker,
+desc, title, metadata,
+pattern, linearGradient, radialGradient,
+script, style,
+symbol {
+  display: none !important;
+}
+
+:host(use) > symbol {
+  display: inline !important;
+}
+
+/*
+:link, :visited {
+  cursor: pointer;
+}
+*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]