1
//! Handling of `xlink:href` and `href` attributes
2
//!
3
//! In SVG1.1, links to elements are done with the `xlink:href` attribute.  However, SVG2
4
//! reduced this to just plain `href` with no namespace:
5
//! <https://svgwg.org/svg2-draft/linking.html#XLinkRefAttrs>
6
//!
7
//! If an element has both `xlink:href` and `href` attributes, the `href` overrides the
8
//! other.  We implement that logic in this module.
9

            
10
use markup5ever::{expanded_name, local_name, namespace_url, ns, ExpandedName};
11

            
12
/// Returns whether the attribute is either of `xlink:href` or `href`.
13
///
14
/// # Example
15
///
16
/// Use with an `if` pattern inside a `match`:
17
///
18
/// ```
19
/// # use markup5ever::{expanded_name, local_name, namespace_url, ns, QualName, Prefix, Namespace, LocalName, ExpandedName};
20
/// # use rsvg::doctest_only::{is_href,set_href};
21
///
22
/// let qual_name = QualName::new(
23
///     Some(Prefix::from("xlink")),
24
///     Namespace::from("http://www.w3.org/1999/xlink"),
25
///     LocalName::from("href"),
26
/// );
27
///
28
/// let value = "some_url";
29
/// let mut my_field: Option<String> = None;
30
///
31
/// match qual_name.expanded() {
32
///     ref name if is_href(name) => set_href(name, &mut my_field, Some(value.to_string())),
33
///     _ => unreachable!(),
34
/// }
35
/// ```
36
3398
pub fn is_href(name: &ExpandedName<'_>) -> bool {
37
3398
    matches!(
38
        *name,
39
        expanded_name!(xlink "href") | expanded_name!("", "href")
40
    )
41
3398
}
42

            
43
/// Sets an `href` attribute in preference over an `xlink:href` one.
44
///
45
/// See [`is_href`] for example usage.
46
696
pub fn set_href<T>(name: &ExpandedName<'_>, dest: &mut Option<T>, href: Option<T>) {
47
1392
    if dest.is_none() || *name != expanded_name!(xlink "href") {
48
696
        *dest = href;
49
    }
50
696
}