Chore: merge validation into macr

This commit is contained in:
Jonathan Kelley committed 2021-01-19 09:08:41 -05:00
1 parent 33a805da40
commit 6c1205e91b
9 files changed
+12 -27

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
//! The html-validation crate provides method that can be used when validating html elements
//! and attributes.
//!
//! The original goal of this crate was to be used as a dependency in procedural macros that
//! validate html at compile time, but it is general purpose and can be used in other problem
//! spaces.
//!
//! ## Potential Strategy - Pessimistic Validation
//!
//! We might make the html-validation crate is pessimistic by nature.
//!
//! This means that as we develop the create we'll blacklist more and more things - but in general
//! we default to not saying that something is invalid until we've specifically encoded that it is
//! not allowed.
//!
//! This means that you'll see methods with names like `is_definitely_invalid_child` - hinting
//! that we're telling you that we're certain that the relationship is not allowed.
//!
//! Over time we'll cover more and more cases and this should become a non issue, but at the
//! beginning it will mean that our validation is less strict than it should really be.
//!
//! The reason behind this strategy is that it lets people get up and running from day one without
//! needing to wait until our validation is perfect.
//! A downside is that as we become more and more strict there might be situations where you have
//! to go back and tweak your html if you had something that we are now calling invalid.
//!
//! ## Potential Strategy - Optimistic Validation
//!
//! In this case we'd make html! generate a compile time error for anything that isn't certainly valid.
//! Then there would be a second macro such as html_unstrict! that would be a bit more permissive.
//!
//! Over time as our validation permitted more cases people could use html! more and more instead of html_loose!
pub mod self_closing;
pub mod svg_namespace;
pub mod valid_tags;
@@ -0,0 +1,31 @@
use lazy_static::lazy_static;
use std::collections::hash_set::HashSet;
use super::svg_namespace::is_self_closing_svg_tag;
// Used to uniquely identify elements that contain closures so that the DomUpdater can
// look them up by their unique id.
// When the DomUpdater sees that the element no longer exists it will drop all of it's
// Rc'd Closures for those events.
lazy_static! {
static ref SELF_CLOSING_TAGS: HashSet<&'static str> = [
"area", "base", "br", "col", "hr", "img", "input", "link", "meta", "param", "command",
"keygen", "source",
]
.iter()
.cloned()
.collect();
}
/// Whether or not this tag is self closing
///
/// ```
/// use html_validation::is_self_closing;
///
/// assert_eq!(is_self_closing("br"), true);
///
/// assert_eq!(is_self_closing("div"), false);
/// ```
pub fn is_self_closing(tag: &str) -> bool {
SELF_CLOSING_TAGS.contains(tag) || is_self_closing_svg_tag(tag)
}
@@ -0,0 +1,114 @@
use lazy_static::lazy_static;
use std::collections::HashMap;
lazy_static! {
// list of svg elements
// https://developer.mozilla.org/en-US/docs/Web/SVG/Element
// a hashmap of `(tag, is_self_closing)`
static ref SVG_NAMESPACED_TAGS: HashMap<&'static str, bool> = [
// TODO: can cause conflict with html `a`
//("a", true),
("animate", true),
("animateMotion", false),
("animateTransform", true),
("circle", true),
("clipPath",false),
// TODO: blocked with [issue](https://github.com/chinedufn/percy/issues/106)
//("color-profile",),
("defs", false),
("desc", false),
("discard", true),
("ellipse",true),
("feBlend", true),
("feColorMatrix", true),
("feComponentTransfer", false),
("feComposite", true),
("feConvolveMatrix", true),
("feDiffuseLighting", false),
("feDisplacementMap", true),
("feDistantLight", true),
("feDropShadow", true),
("feFlood", true),
("feFuncA", true),
("feFuncB", true),
("feFuncG", true),
("feFuncR", true),
("feGaussianBlur", true),
("feImage", true),
("feMerge", false),
("feMergeNode", true),
("feMorphology", true),
("feOffset", true),
("fePointLight", true),
("feSpecularLighting", false),
("feSpotLight", true),
("feTile", true),
("feTurbulence", true),
("filter", false),
("foreignObject", false),
("g",false),
("hatch", false),
("hatchpath", true),
("image", true),
("line", true),
("linearGradient", false),
("marker", false),
("mask", false),
// TODO: undocumented
//("mesh",),
// TODO: undocumented
//("meshgradient",),
// TODO: undocumented
//("meshpatch",),
// TODO: undocumented
//("meshrow",),
("metadata", false),
("mpath", true),
("path", true),
("pattern", false),
("polygon", true),
("polyline", true),
("radialGradient", false),
("rect", true),
// TODO: can cause conflict with html `script` tag
//("script", false),
("set", true),
("solidcolor", true),
("stop", true),
// TODO: can cause conflict with html `style` tag
//("style", false),
("svg", false),
("switch", false),
("symbol", false),
("text", false),
("textPath", false),
// TODO: can cause conflict with html `title` tag
//("title", false),
("tspan", false),
// TODO: undocumented
//("unknown",),
("use", true),
("view", true),
]
.iter()
.cloned()
.collect();
}
/// Whether or not this tag is part svg elements
/// ```
/// use html_validation::is_svg_namespace;
///
/// assert_eq!(is_svg_namespace("svg"), true);
///
/// assert_eq!(is_svg_namespace("circle"), true);
///
/// assert_eq!(is_svg_namespace("div"), false);
/// ```
pub fn is_svg_namespace(tag: &str) -> bool {
SVG_NAMESPACED_TAGS.contains_key(tag)
}
/// Whether or not this svg tag is self closing
pub(crate) fn is_self_closing_svg_tag(tag: &str) -> bool {
SVG_NAMESPACED_TAGS.get(tag).map(|v| *v).unwrap_or(false)
}
@@ -0,0 +1,138 @@
use lazy_static::lazy_static;
use std::collections::hash_set::HashSet;
use super::svg_namespace::is_svg_namespace;
lazy_static! {
static ref VALID_TAGS: HashSet<&'static str> = [
"a",
"abbr",
"address",
"area",
"article",
"aside",
"audio",
"b",
"base",
"bdi",
"bdo",
"big",
"blockquote",
"body",
"br",
"button",
"canvas",
"caption",
"cite",
"code",
"col",
"colgroup",
"command",
"data",
"datalist",
"dd",
"del",
"details",
"dfn",
"dialog",
"div",
"dl",
"dt",
"em",
"embed",
"fieldset",
"figcaption",
"figure",
"footer",
"form",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"head",
"header",
"hr",
"html",
"i",
"iframe",
"img",
"input",
"ins",
"kbd",
"keygen",
"label",
"legend",
"li",
"link",
"main",
"map",
"mark",
"menu",
"menuitem",
"meta",
"meter",
"nav",
"noscript",
"object",
"ol",
"optgroup",
"option",
"output",
"p",
"param",
"picture",
"pre",
"progress",
"q",
"rp",
"rt",
"ruby",
"s",
"samp",
"script",
"section",
"select",
"small",
"source",
"span",
"strong",
"style",
"sub",
"summary",
"sup",
"table",
"tbody",
"td",
"textarea",
"tfoot",
"th",
"thead",
"time",
"title",
"tr",
"track",
"u",
"ul",
"var",
"video",
"wbr",
]
.iter()
.cloned()
.collect();
}
/// Whether or not this tag is valid
///
/// ```
/// use html_validation::is_valid_tag;
///
/// assert_eq!(is_valid_tag("br"), true);
///
/// assert_eq!(is_valid_tag("random"), false);
/// ```
pub fn is_valid_tag(tag: &str) -> bool {
VALID_TAGS.contains(tag) || is_svg_namespace(tag)
}