diff --git a/packages/mrml-core/lib/html-compare/src/lib.rs b/packages/mrml-core/lib/html-compare/src/lib.rs index 9064c720..ee52f81b 100644 --- a/packages/mrml-core/lib/html-compare/src/lib.rs +++ b/packages/mrml-core/lib/html-compare/src/lib.rs @@ -248,7 +248,7 @@ fn compare_elements<'a>( let ending = compare_attributes(cursor, expected.clone(), generated.clone())?; if matches!(ending.end, HtmlElementEnd::Open) - && !["br", "meta"].contains(&expected.local.as_str()) + && !matches!(expected.local.as_str(), "br" | "meta") { compare_all(cursor, &expected.local, expected.span, generated.span)?; } diff --git a/packages/mrml-core/resources/compare/success/mj-raw.html b/packages/mrml-core/resources/compare/success/mj-raw.html index dfcc6cae..ec6061e4 100644 --- a/packages/mrml-core/resources/compare/success/mj-raw.html +++ b/packages/mrml-core/resources/compare/success/mj-raw.html @@ -64,10 +64,10 @@ Hello Something - + - \ No newline at end of file + diff --git a/packages/mrml-core/src/mj_body/parse.rs b/packages/mrml-core/src/mj_body/parse.rs index ee5cd843..53a32699 100644 --- a/packages/mrml-core/src/mj_body/parse.rs +++ b/packages/mrml-core/src/mj_body/parse.rs @@ -20,9 +20,9 @@ use crate::mj_table::NAME as MJ_TABLE; use crate::mj_text::NAME as MJ_TEXT; use crate::mj_wrapper::NAME as MJ_WRAPPER; use crate::node::Node; +use crate::prelude::is_void_element; use crate::prelude::parser::{ - parse_attributes_map, should_ignore_children, Error, MrmlCursor, MrmlParser, MrmlToken, - ParseChildren, ParseElement, + parse_attributes_map, Error, MrmlCursor, MrmlParser, MrmlToken, ParseChildren, ParseElement, }; #[cfg(feature = "async")] use crate::prelude::parser::{AsyncMrmlParser, AsyncParseChildren, AsyncParseElement}; @@ -37,7 +37,7 @@ impl<'opts> ParseElement> for MrmlParser<'opts> { let tag = tag.to_string(); let attributes = parse_attributes_map(cursor)?; let ending = cursor.assert_element_end()?; - if ending.empty || should_ignore_children(tag.as_str()) { + if ending.empty || is_void_element(tag.as_str()) { return Ok(Node { tag, attributes, @@ -68,7 +68,7 @@ impl AsyncParseElement> for AsyncMrmlParser { let tag = tag.to_string(); let attributes = parse_attributes_map(cursor)?; let ending = cursor.assert_element_end()?; - if ending.empty || should_ignore_children(tag.as_str()) { + if ending.empty || is_void_element(tag.as_str()) { return Ok(Node { tag, attributes, diff --git a/packages/mrml-core/src/mj_raw/parse.rs b/packages/mrml-core/src/mj_raw/parse.rs index 1a167296..bb2d4d47 100644 --- a/packages/mrml-core/src/mj_raw/parse.rs +++ b/packages/mrml-core/src/mj_raw/parse.rs @@ -3,12 +3,12 @@ use xmlparser::StrSpan; use super::{MjRaw, MjRawChild}; use crate::comment::Comment; use crate::node::Node; -use crate::prelude::parser::{ - should_ignore_children, Error, MrmlCursor, MrmlParser, MrmlToken, ParseAttributes, - ParseChildren, ParseElement, -}; +use crate::prelude::is_void_element; #[cfg(feature = "async")] use crate::prelude::parser::{AsyncMrmlParser, AsyncParseChildren, AsyncParseElement}; +use crate::prelude::parser::{ + Error, MrmlCursor, MrmlParser, MrmlToken, ParseAttributes, ParseChildren, ParseElement, +}; use crate::text::Text; impl<'opts> ParseElement> for MrmlParser<'opts> { @@ -19,7 +19,7 @@ impl<'opts> ParseElement> for MrmlParser<'opts> { ) -> Result, Error> { let attributes = self.parse_attributes(cursor)?; let ending = cursor.assert_element_end()?; - if ending.empty || should_ignore_children(tag.as_str()) { + if ending.empty || is_void_element(tag.as_str()) { return Ok(Node { tag: tag.to_string(), attributes, @@ -49,7 +49,7 @@ impl AsyncParseElement> for AsyncMrmlParser { ) -> Result, Error> { let attributes = self.parse_attributes(cursor)?; let ending = cursor.assert_element_end()?; - if ending.empty || should_ignore_children(tag.as_str()) { + if ending.empty || is_void_element(tag.as_str()) { return Ok(Node { tag: tag.to_string(), attributes, diff --git a/packages/mrml-core/src/node/render.rs b/packages/mrml-core/src/node/render.rs index 27c25a27..2f5fa399 100644 --- a/packages/mrml-core/src/node/render.rs +++ b/packages/mrml-core/src/node/render.rs @@ -2,10 +2,9 @@ use std::cell::{Ref, RefCell}; use std::rc::Rc; use super::Node; +use crate::prelude::is_void_element; use crate::prelude::render::{Error, Header, Render, RenderOptions, Renderable}; -const SHOULD_SELF_CLOSE: [&str; 1] = ["script"]; - struct NodeRender<'e, 'h, T> { header: Rc>>, element: &'e Node, @@ -33,10 +32,14 @@ where buf.push_str(value); buf.push('"'); } - if self.element.children.is_empty() - && !SHOULD_SELF_CLOSE.contains(&self.element.tag.as_str()) - { - buf.push_str(" />"); + if self.element.children.is_empty() { + if is_void_element(self.element.tag.as_str()) { + buf.push_str(" />"); + } else { + buf.push_str(">'); + } } else { buf.push('>'); for (index, child) in self.element.children.iter().enumerate() { diff --git a/packages/mrml-core/src/prelude/mod.rs b/packages/mrml-core/src/prelude/mod.rs index e1611aa6..63945a5f 100644 --- a/packages/mrml-core/src/prelude/mod.rs +++ b/packages/mrml-core/src/prelude/mod.rs @@ -6,3 +6,25 @@ pub mod print; pub mod render; pub mod hash; + +// see https://developer.mozilla.org/en-US/docs/Glossary/Void_element +#[cfg(any(feature = "parser", feature = "render"))] +pub(crate) fn is_void_element(tag: &str) -> bool { + matches!( + tag, + "area" + | "base" + | "br" + | "col" + | "embed" + | "hr" + | "img" + | "input" + | "link" + | "meta" + | "param" + | "source" + | "track" + | "wbr" + ) +} diff --git a/packages/mrml-core/src/prelude/parser/mod.rs b/packages/mrml-core/src/prelude/parser/mod.rs index 29c8c292..00f55008 100644 --- a/packages/mrml-core/src/prelude/parser/mod.rs +++ b/packages/mrml-core/src/prelude/parser/mod.rs @@ -15,26 +15,6 @@ pub mod memory_loader; pub mod multi_loader; pub mod noop_loader; -pub(crate) fn should_ignore_children(tag: &str) -> bool { - matches!( - tag, - "area" - | "base" - | "br" - | "col" - | "embed" - | "hr" - | "img" - | "input" - | "link" - | "meta" - | "param" - | "source" - | "track" - | "wbr" - ) -} - #[derive(Clone, Debug, Default)] pub struct Span { pub start: usize,