[librsvg: 16/20] Assign the empty namespace to the "id" attribute



commit 76ae72216aac14e6d28ae2f628356349d3ea8e39
Author: Federico Mena Quintero <federico gnome org>
Date:   Sat Oct 26 11:19:10 2019 -0500

    Assign the empty namespace to the "id" attribute
    
    This is my interpretation of https://www.w3.org/TR/xml-names11/
    section "7 Conformance of Documents" - "No attributes with a declared
    type of ID [...] contain any colons."
    
    Fixes the text-tref-02 test, which has a non-SVG subtree like
    
      <foo xmlns="http://example.org/foo";>
        <bar id="world">World</bar>
      </foo>
    
    And yet we must pick up the id attribute in the bar element.

 rsvg_internals/src/create_node.rs  |  2 +-
 rsvg_internals/src/property_bag.rs | 30 ++++++++++++++++++++++--------
 2 files changed, 23 insertions(+), 9 deletions(-)
---
diff --git a/rsvg_internals/src/create_node.rs b/rsvg_internals/src/create_node.rs
index cdbb6b51..8f4cc33a 100644
--- a/rsvg_internals/src/create_node.rs
+++ b/rsvg_internals/src/create_node.rs
@@ -238,7 +238,7 @@ pub fn create_node_and_register_id(
 
     for (attr, value) in pbag.iter() {
         match attr.expanded() {
-            expanded_name!(svg "id") => id = Some(value),
+            expanded_name!("", "id") => id = Some(value),
             expanded_name!(svg "class") => class = Some(value),
             _ => (),
         }
diff --git a/rsvg_internals/src/property_bag.rs b/rsvg_internals/src/property_bag.rs
index 90503c32..f4d3e2b9 100644
--- a/rsvg_internals/src/property_bag.rs
+++ b/rsvg_internals/src/property_bag.rs
@@ -4,7 +4,7 @@ use std::mem;
 use std::slice;
 use std::str;
 
-use markup5ever::{LocalName, Namespace, Prefix, QualName};
+use markup5ever::{namespace_url, ns, LocalName, Namespace, Prefix, QualName};
 
 use crate::util::{opt_utf8_cstr, utf8_cstr};
 
@@ -51,15 +51,29 @@ impl<'a> PropertyBag<'a> {
 
                 assert!(!localname.is_null());
 
-                let prefix = opt_utf8_cstr(prefix);
-                let uri = opt_utf8_cstr(uri);
                 let localname = utf8_cstr(localname);
 
-                let qual_name = QualName::new(
-                    prefix.map(Prefix::from),
-                    uri.map(Namespace::from).unwrap_or_else(|| element_ns.clone()),
-                    LocalName::from(localname)
-                );
+                let qual_name = if localname == "id" {
+                    // https://www.w3.org/TR/xml-names11/ section "7 Conformance of Documents"
+                    // "No attributes with a declared type of ID [...] contain any colons."
+                    //
+                    // I'm interpreting this to mean that the id attribute has no
+                    // namespace.
+
+                    QualName::new(None, ns!(), LocalName::from(localname))
+                } else {
+                    let prefix = opt_utf8_cstr(prefix);
+                    let uri = opt_utf8_cstr(uri);
+
+                    // Use the namespace URI from the attribute, or if it is missing,
+                    // use the element's namespace, per section "6.2 Namespace Defaulting"
+                    // of https://www.w3.org/TR/xml-names11/
+                    QualName::new(
+                        prefix.map(Prefix::from),
+                        uri.map(Namespace::from).unwrap_or_else(|| element_ns.clone()),
+                        LocalName::from(localname)
+                    )
+                };
 
                 if !value_start.is_null() && !value_end.is_null() {
                     assert!(value_end >= value_start);


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