sauron_core/html/
lookup.rs

1//! Provides list of HTML and SVG tags, style properties
2use crate::{
3    html::{
4        attributes::{HTML_ATTRS, HTML_ATTRS_SPECIAL},
5        tags::{
6            commons::HTML_TAGS, self_closing::HTML_SC_TAGS, HTML_TAGS_NON_COMMON,
7            HTML_TAGS_WITH_MACRO_NON_COMMON,
8        },
9    },
10    svg::{
11        attributes::{SVG_ATTRS, SVG_ATTRS_SPECIAL, SVG_ATTRS_XLINK},
12        tags::{commons::SVG_TAGS, special::SVG_TAGS_SPECIAL, SVG_TAGS_NON_COMMON},
13        SVG_NAMESPACE,
14    },
15};
16use once_cell::sync::Lazy;
17use std::collections::BTreeMap;
18use std::collections::BTreeSet;
19pub use style_lookup::match_property;
20mod style_lookup;
21
22/// All of the svg tags
23static ALL_SVG_TAGS: Lazy<BTreeSet<&&'static str>> = Lazy::new(|| {
24    SVG_TAGS
25        .iter()
26        .chain(SVG_TAGS_NON_COMMON.iter())
27        .chain(SVG_TAGS_SPECIAL.iter().map(|(_func, t)| t))
28        .collect()
29});
30
31/// All of the html tags, excluding the SVG tags.
32static ALL_HTML_TAGS: Lazy<BTreeSet<&&'static str>> = Lazy::new(|| {
33    HTML_TAGS
34        .iter()
35        .chain(HTML_SC_TAGS.iter())
36        .chain(HTML_TAGS_NON_COMMON.iter())
37        .chain(HTML_TAGS_WITH_MACRO_NON_COMMON.iter())
38        .collect()
39});
40
41static SELF_CLOSING_TAGS: Lazy<BTreeSet<&&'static str>> =
42    Lazy::new(|| HTML_SC_TAGS.iter().collect());
43
44static ALL_ATTRS: Lazy<BTreeMap<&'static str, &'static str>> = Lazy::new(|| {
45    BTreeMap::from_iter(
46        HTML_ATTRS
47            .iter()
48            .chain(SVG_ATTRS.iter())
49            .map(|att| (*att, *att))
50            .chain(
51                HTML_ATTRS_SPECIAL
52                    .iter()
53                    .chain(SVG_ATTRS_SPECIAL.iter())
54                    .chain(SVG_ATTRS_XLINK.iter())
55                    .map(|(func, att)| (*func, *att)),
56            ),
57    )
58});
59
60/// Find the namespace of this tag
61/// if the arg tag is an SVG tag, return the svg namespace
62/// html tags don't need to have namespace while svg does, otherwise it will not be properly
63/// mounted into the DOM
64///
65/// Limitations: `script`, `style`,and `a` used inside svg will return `None`, as these are also valid html tags.
66pub fn tag_namespace(tag: &str) -> Option<&'static str> {
67    let is_html = ALL_HTML_TAGS.contains(&tag);
68    let is_svg = ALL_SVG_TAGS.contains(&tag);
69    if !is_html {
70        if is_svg {
71            // we return the svg namespace only when the tag is not an html, but an svg tag
72            // False negatives:
73            // This means that script, style, a and title used inside in svg tag will not work
74            // properly, since this 3 tags are valid html tags
75            Some(SVG_NAMESPACE)
76        } else {
77            None
78        }
79    } else {
80        None
81    }
82}
83
84/// return the matching attribute
85pub fn match_attribute(att: &str) -> Option<&'static str> {
86    ALL_ATTRS
87        .iter()
88        .find(|(_k, v)| v == &&att)
89        .map(|(_k, v)| *v)
90}
91
92/// given the attribute return the function name
93pub fn attribute_function(att: &str) -> Option<&'static str> {
94    ALL_ATTRS
95        .iter()
96        .find(|(_k, v)| v == &&att)
97        .map(|(k, _v)| *k)
98}
99
100/// return the matching tag
101pub fn match_tag(tag: &str) -> Option<&'static str> {
102    ALL_HTML_TAGS
103        .iter()
104        .chain(ALL_SVG_TAGS.iter())
105        .find(|t| **t == &tag)
106        .map(|t| **t)
107}
108
109/// Returns true if this html tag is self closing
110#[inline]
111pub fn is_self_closing(tag: &str) -> bool {
112    SELF_CLOSING_TAGS.contains(&tag)
113}