[librsvg: 3/4] (#403): Apply the CSS and "style" attribute at the end of loading



commit 5fbd63670975c4810673fd48e93943e70d221ccb
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri May 3 19:21:07 2019 -0500

    (#403): Apply the CSS and "style" attribute at the end of loading
    
    This removes the special case for NodeSvg, which delayed its own
    setting of the style properties.  Now this is done for all nodes at
    the end of the loading process.
    
    This is done in Node::set_styles_recursively(), essentially a new pass
    over the tree before ::cascade().
    
    Fixes https://gitlab.gnome.org/GNOME/librsvg/issues/403

 rsvg_internals/src/node.rs      | 10 +++++++++-
 rsvg_internals/src/structure.rs |  5 -----
 rsvg_internals/src/xml.rs       | 37 +++++++++++++++----------------------
 3 files changed, 24 insertions(+), 28 deletions(-)
---
diff --git a/rsvg_internals/src/node.rs b/rsvg_internals/src/node.rs
index 33c3fd46..e474ffd4 100644
--- a/rsvg_internals/src/node.rs
+++ b/rsvg_internals/src/node.rs
@@ -349,6 +349,14 @@ impl Node {
         }
     }
 
+    pub fn set_styles_recursively(&self, css_rules: &CssRules) {
+        self.set_style(css_rules);
+
+        for child in self.children() {
+            child.set_styles_recursively(css_rules);
+        }
+    }
+
     pub fn get_cond(&self) -> bool {
         self.data.cond.get()
     }
@@ -570,7 +578,7 @@ impl Node {
 
     // Sets the node's specified values from the style-related attributes in the pbag.
     // Also applies CSS rules in our limited way based on the node's tag/class/id.
-    pub fn set_style(&self, css_rules: &CssRules) {
+    fn set_style(&self, css_rules: &CssRules) {
         self.set_css_styles(css_rules);
         self.set_style_attribute();
     }
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 171e0fd1..0994fc9e 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -6,7 +6,6 @@ use cairo::Rectangle;
 use crate::allowed_url::Fragment;
 use crate::aspect_ratio::*;
 use crate::attributes::Attribute;
-use crate::css::CssRules;
 use crate::dpi::Dpi;
 use crate::drawing_ctx::{ClipMode, DrawingCtx, ViewParams};
 use crate::error::{AttributeResultExt, RenderingError};
@@ -127,10 +126,6 @@ impl NodeSvg {
         }
     }
 
-    pub fn set_delayed_style(&self, node: &RsvgNode, css_rules: &CssRules) {
-        node.set_style(css_rules);
-    }
-
     pub fn get_size(&self, values: &ComputedValues, dpi: Dpi) -> Option<(i32, i32)> {
         let (_, _, w, h) = self.get_unnormalized_viewport();
 
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index 08e8b85d..d5a68188 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -16,7 +16,6 @@ use crate::handle::LoadOptions;
 use crate::io::{self, get_input_stream_for_loading};
 use crate::node::{node_new, Node, NodeType, RsvgNode};
 use crate::property_bag::PropertyBag;
-use crate::structure::NodeSvg;
 use crate::style::NodeStyle;
 use crate::svg::Svg;
 use crate::text::NodeChars;
@@ -115,14 +114,22 @@ impl XmlState {
     pub fn steal_result(&mut self) -> Result<Svg, LoadingError> {
         match self.tree_root {
             None => Err(LoadingError::SvgHasNoElements),
-            Some(ref root) if root.get_type() != NodeType::Svg => {
-                Err(LoadingError::RootElementIsNotSvg)
+
+            Some(ref root) => {
+                if root.get_type() == NodeType::Svg {
+                    let root = self.tree_root.take().unwrap();
+
+                    root.set_styles_recursively(self.css_rules.as_ref().unwrap());
+
+                    Ok(Svg::new(
+                        root,
+                        self.ids.take().unwrap(),
+                        self.load_options.clone(),
+                    ))
+                } else {
+                    Err(LoadingError::RootElementIsNotSvg)
+                }
             }
-            _ => Ok(Svg::new(
-                self.tree_root.take().unwrap(),
-                self.ids.take().unwrap(),
-                self.load_options.clone(),
-            )),
         }
     }
 
@@ -264,14 +271,6 @@ impl XmlState {
     fn element_creation_end_element(&mut self) {
         let node = self.current_node.take().unwrap();
 
-        // The "svg" node is special; it parses its style attributes
-        // here, not during element creation.
-        if node.get_type() == NodeType::Svg {
-            node.with_impl(|svg: &NodeSvg| {
-                svg.set_delayed_style(&node, self.css_rules.as_ref().unwrap());
-            });
-        }
-
         if node.get_type() == NodeType::Style {
             let css_data = node.with_impl(|style: &NodeStyle| style.get_css(&node));
 
@@ -323,12 +322,6 @@ impl XmlState {
 
         new_node.set_atts(&new_node, pbag, self.load_options.locale());
 
-        // The "svg" node is special; it will parse its style attributes
-        // until the end, in standard_element_end().
-        if new_node.get_type() != NodeType::Svg {
-            new_node.set_style(self.css_rules.as_ref().unwrap());
-        }
-
         new_node.set_overridden_properties();
 
         new_node


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