[librsvg: 1/3] New href module to deal with xlink:href vs. href




commit c244f0df056e9e7f57f4ea59a7470ec581706c22
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Aug 18 19:27:30 2020 -0500

    New href module to deal with xlink:href vs. href

 Makefile.am                |  1 +
 rsvg_internals/src/href.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++++
 rsvg_internals/src/lib.rs  |  1 +
 3 files changed, 51 insertions(+)
---
diff --git a/Makefile.am b/Makefile.am
index 4d909d193..00a77a3ec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -68,6 +68,7 @@ LIBRSVG_INTERNALS_SRC =                                               \
        rsvg_internals/src/font_props.rs                        \
        rsvg_internals/src/gradient.rs                          \
        rsvg_internals/src/handle.rs                            \
+       rsvg_internals/src/href.rs                              \
        rsvg_internals/src/image.rs                             \
        rsvg_internals/src/io.rs                                \
        rsvg_internals/src/iri.rs                               \
diff --git a/rsvg_internals/src/href.rs b/rsvg_internals/src/href.rs
new file mode 100644
index 000000000..c5bf466e4
--- /dev/null
+++ b/rsvg_internals/src/href.rs
@@ -0,0 +1,49 @@
+//! Handling of `xlink:href` and `href` attributes
+//!
+//! In SVG1.1, links to elements are done with the `xlink:href` attribute.  However, SVG2
+//! reduced this to just plain `href` with no namespace:
+//! https://svgwg.org/svg2-draft/linking.html#XLinkRefAttrs
+//!
+//! If an element has both `xlink:href` and `href` attributes, the `href` overrides the
+//! other.  We implement that logic in this module.
+
+use markup5ever::{ExpandedName, expanded_name, local_name, namespace_url, ns};
+
+/// Returns whether the attribute is either of `xlink:href` or `href`.
+///
+/// # Example
+///
+/// Use with an `if` pattern inside a `match`:
+///
+/// ```ignore
+/// # use markup5ever::{LocalName, Namespace, Prefix, QualName, namespace_url};
+/// let qual_name = QualName::new(
+///     Some(Prefix::from("xlink")),
+///     Namespace::from("http://www.w3.org/1999/xlink";),
+///     LocalName::from("href"),
+/// );
+///
+/// // assume foo is an Option<Value>
+/// // assume value is a Value
+///
+/// match qual_name.expanded() {
+///     ref name if is_href(name) => set_href(name, &mut foo, value),
+///     _ => unreachable!(),
+/// }
+/// ```
+pub fn is_href(name: &ExpandedName) -> bool {
+    match *name {
+        expanded_name!(xlink "href")
+            | expanded_name!("", "href") => true,
+        _ => false,
+    }
+}
+
+/// Sets an `href` attribute in preference over an `xlink:href` one.
+///
+/// See [`is_href`](#fn.is_href.html) for example usage.
+pub fn set_href<T>(name: &ExpandedName, dest: &mut Option<T>, href: T) {
+    if dest.is_none() || *name != expanded_name!(xlink "href") {
+        *dest = Some(href);
+    }
+}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index b4d88dc08..c0bcb9b1c 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -107,6 +107,7 @@ pub mod filters;
 mod font_props;
 mod gradient;
 mod handle;
+mod href;
 mod image;
 mod io;
 mod iri;


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