[librsvg: 2/3] properties: do not override presentation attributes for ua.css



commit 03d820f35306498b10eb0281c6ccaba8ae3e94e1
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Mar 22 13:59:10 2020 +0100

    properties: do not override presentation attributes for ua.css
    
    Presentation attributes should be considered with the same
    priority of the author css, hence have higher priority than the
    user agent css.

 rsvg_internals/src/css.rs        |  2 +-
 rsvg_internals/src/element.rs    | 20 ++++++++++++--------
 rsvg_internals/src/properties.rs | 37 +++++++++++++++++++++++++++----------
 3 files changed, 40 insertions(+), 19 deletions(-)
---
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index 57e74031..79e11b73 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -764,7 +764,7 @@ pub fn cascade(
 
         for m in matches {
             node.borrow_element_mut()
-                .apply_style_declaration(m.declaration);
+                .apply_style_declaration(m.declaration, m.origin);
         }
 
         node.borrow_element_mut().set_style_attribute();
diff --git a/rsvg_internals/src/element.rs b/rsvg_internals/src/element.rs
index 486d54fa..2b44ddb5 100644
--- a/rsvg_internals/src/element.rs
+++ b/rsvg_internals/src/element.rs
@@ -14,7 +14,7 @@ use std::fmt;
 
 use crate::bbox::BoundingBox;
 use crate::cond::{RequiredExtensions, RequiredFeatures, SystemLanguage};
-use crate::css::Declaration;
+use crate::css::{Declaration, Origin};
 use crate::document::AcquiredNodes;
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
@@ -332,18 +332,22 @@ impl Element {
     }
 
     // Applies a style declaration to the node's specified_values
-    pub fn apply_style_declaration(&mut self, declaration: &Declaration) {
-        self.specified_values
-            .set_property_from_declaration(declaration, &mut self.important_styles);
+    pub fn apply_style_declaration(&mut self, declaration: &Declaration, origin: Origin) {
+        self.specified_values.set_property_from_declaration(
+            declaration,
+            origin,
+            &mut self.important_styles,
+        );
     }
 
     /// Applies CSS styles from the saved value of the "style" attribute
     pub fn set_style_attribute(&mut self) {
         if !self.style_attr.is_empty() {
-            if let Err(e) = self
-                .specified_values
-                .parse_style_declarations(self.style_attr.as_str(), &mut self.important_styles)
-            {
+            if let Err(e) = self.specified_values.parse_style_declarations(
+                self.style_attr.as_str(),
+                Origin::Author,
+                &mut self.important_styles,
+            ) {
                 self.set_error(e);
             }
 
diff --git a/rsvg_internals/src/properties.rs b/rsvg_internals/src/properties.rs
index 277705ae..389eb3de 100644
--- a/rsvg_internals/src/properties.rs
+++ b/rsvg_internals/src/properties.rs
@@ -6,7 +6,7 @@ use cssparser::{
 use markup5ever::{expanded_name, local_name, namespace_url, ns, QualName};
 use std::collections::HashSet;
 
-use crate::css::{DeclParser, Declaration};
+use crate::css::{DeclParser, Declaration, Origin};
 use crate::error::*;
 use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
@@ -496,7 +496,7 @@ impl SpecifiedValues {
         }
     }
 
-    fn replace_property(&mut self, prop: &ParsedProperty) {
+    fn set_property(&mut self, prop: &ParsedProperty, replace: bool) {
         let id = prop.get_property_id();
 
         if id == PropertyId::Marker {
@@ -504,7 +504,9 @@ impl SpecifiedValues {
         }
 
         if let Some(index) = self.property_index(id) {
-            self.props[index] = prop.clone();
+            if replace {
+                self.props[index] = prop.clone();
+            }
         } else {
             self.props.push(prop.clone());
             let pos = self.props.len() - 1;
@@ -513,20 +515,29 @@ impl SpecifiedValues {
     }
 
     #[rustfmt::skip]
-    pub fn set_parsed_property(&mut self, prop: &ParsedProperty) {
+    fn set_property_expanding_shorthands(&mut self, prop: &ParsedProperty, replace: bool) {
         use crate::properties::ParsedProperty::*;
         use crate::properties as p;
 
         if let Marker(SpecifiedValue::Specified(p::Marker(ref v))) = *prop {
             // Since "marker" is a shorthand property, we'll just expand it here
-            self.replace_property(&MarkerStart(SpecifiedValue::Specified(p::MarkerStart(v.clone()))));
-            self.replace_property(&MarkerMid(SpecifiedValue::Specified(p::MarkerMid(v.clone()))));
-            self.replace_property(&MarkerEnd(SpecifiedValue::Specified(p::MarkerEnd(v.clone()))));
+            self.set_property(&MarkerStart(SpecifiedValue::Specified(p::MarkerStart(v.clone()))), replace);
+            self.set_property(&MarkerMid(SpecifiedValue::Specified(p::MarkerMid(v.clone()))), replace);
+            self.set_property(&MarkerEnd(SpecifiedValue::Specified(p::MarkerEnd(v.clone()))), replace);
         } else {
-            self.replace_property(prop);
+            self.set_property(prop, replace);
         }
     }
 
+    pub fn set_parsed_property(&mut self, prop: &ParsedProperty) {
+        self.set_property_expanding_shorthands(prop, true);
+    }
+
+    /* user agent property have less priority than presentation attributes */
+    pub fn set_parsed_property_user_agent(&mut self, prop: &ParsedProperty) {
+        self.set_property_expanding_shorthands(prop, false);
+    }
+
     pub fn to_computed_values(&self, computed: &mut ComputedValues) {
         macro_rules! compute {
             ($name:ident, $field:ident) => {
@@ -726,6 +737,7 @@ impl SpecifiedValues {
     pub fn set_property_from_declaration(
         &mut self,
         declaration: &Declaration,
+        origin: Origin,
         important_styles: &mut HashSet<QualName>,
     ) {
         if !declaration.important && important_styles.contains(&declaration.prop_name) {
@@ -736,12 +748,17 @@ impl SpecifiedValues {
             important_styles.insert(declaration.prop_name.clone());
         }
 
-        self.set_parsed_property(&declaration.property);
+        if origin == Origin::UserAgent {
+            self.set_parsed_property_user_agent(&declaration.property);
+        } else {
+            self.set_parsed_property(&declaration.property);
+        }
     }
 
     pub fn parse_style_declarations(
         &mut self,
         declarations: &str,
+        origin: Origin,
         important_styles: &mut HashSet<QualName>,
     ) -> Result<(), ElementError> {
         let mut input = ParserInput::new(declarations);
@@ -755,7 +772,7 @@ impl SpecifiedValues {
                     None
                 }
             })
-            .for_each(|decl| self.set_property_from_declaration(&decl, important_styles));
+            .for_each(|decl| self.set_property_from_declaration(&decl, origin, important_styles));
 
         Ok(())
     }


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