Skip to content

Commit

Permalink
Fix void elements having closing tags (#49)
Browse files Browse the repository at this point in the history
According to HTML spec a void elements has neither content nor a closing tag
  • Loading branch information
kelko committed Oct 5, 2022
1 parent 97a791d commit 8c0faa2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/parser/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ use super::{handle::NodeHandle, Parser};

const INLINED_ATTRIBUTES: usize = 2;
const INLINED_SUBNODES: usize = 2;
const HTML_VOID_ELEMENTS: [&str; 16] = [
"area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link",
"meta", "param", "source", "track", "wbr",
];

/// The type of map for "raw" attributes
pub type RawAttributesMap<'a> = InlineHashMap<Bytes<'a>, Option<Bytes<'a>>, INLINED_ATTRIBUTES>;
Expand Down Expand Up @@ -287,7 +291,9 @@ impl<'a> HTMLTag<'a> {
///
/// Equivalent to [Element#outerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML) in browsers)
pub fn outer_html<'p>(&'p self, parser: &'p Parser<'a>) -> String {
let mut outer_html = format!("<{}", self._name.as_utf8_str());
let tag_name = self._name.as_utf8_str();
let is_void_element = HTML_VOID_ELEMENTS.contains(&tag_name.as_ref());
let mut outer_html = format!("<{}", &tag_name);

#[inline]
fn write_attribute(dest: &mut String, k: Cow<str>, v: Option<Cow<str>>) {
Expand All @@ -310,6 +316,11 @@ impl<'a> HTMLTag<'a> {

outer_html.push('>');

// void elements have neither content nor a closing tag.
if is_void_element {
return outer_html;
}

// TODO(y21): More of an idea than a TODO, but a potential perf improvement
// could be having some kind of internal inner_html function that takes a &mut String
// and simply writes to it instead of returning a newly allocated string for every element
Expand Down
10 changes: 10 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ fn outer_html() {
assert_eq!(tag.outer_html(parser), "<p>test<span>a</span></p>");
}

#[test]
fn outer_html_void_elements() {
const HTML_INPUT: &str = r#"<html><head></head><body><img src=""><br><hr></body></html>"#;
let vdom = parse(HTML_INPUT, ParserOptions::default()).unwrap();
assert_eq!(
r#"<html><head></head><body><img src=""><br><hr></body></html>"#,
vdom.outer_html()
);
}

#[test]
fn inner_html() {
let dom = parse(
Expand Down

0 comments on commit 8c0faa2

Please sign in to comment.