Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/Html/HtmlParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,18 @@ type HtmlNode =
static member NewCData content = HtmlCData(content)

override x.ToString() =
let isVoidElement =
let set =
[| "area"; "base"; "br"; "col"; "command"; "embed"; "hr"; "img"; "input"
"keygen"; "link"; "meta"; "param"; "source"; "track"; "wbr" |]
|> Set.ofArray
fun name -> Set.contains name set
let rec serialize (sb:StringBuilder) indentation canAddNewLine html =
let append (str:string) = sb.Append str |> ignore
let appendEndTag name =
append "</"
append name
append ">"
let shouldAppendEndTag name =
name = "textarea"
let newLine plus =
sb.AppendLine() |> ignore
String(' ', indentation + plus) |> append
Expand All @@ -117,12 +121,11 @@ type HtmlNode =
append "=\""
append value
append "\""
if elements.IsEmpty then
if shouldAppendEndTag name then
append ">"
appendEndTag name
else
append " />"
if isVoidElement name then
append " />"
elif elements.IsEmpty then
append ">"
appendEndTag name
else
append ">"
if not onlyText then
Expand Down
17 changes: 15 additions & 2 deletions tests/FSharp.Data.Tests/HtmlParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,19 @@ let ``Renders textarea closing tag``() =

result |> should equal """<textarea cols="40" rows="2"></textarea>"""

[<Test>]
let ``Renders self-closing tag for void elements``() =
[ "area"; "base"; "br"; "col"; "command"; "embed"; "hr"; "img"; "input"
"keygen"; "link"; "meta"; "param"; "source"; "track"; "wbr" ]
|> List.iter (fun name ->
let html = HtmlNode.NewElement name |> string
html |> should equal $"<%s{name} />")

[<Test>]
let ``Renders no self-closing tag for non-void elements``() =
let html = HtmlNode.NewElement "foo" |> string
html |> should equal "<foo></foo>"

[<Test>]
let ``Can handle CDATA blocks``() =
let cData = """
Expand Down Expand Up @@ -911,9 +924,9 @@ let ``Parsing non-html content doesn't cause an infinite loop - Github-1264``()
[<Test; Timeout(2000)>]
let ``Can handle incomplete tags at end of file without creating an infinite loop``() =
let result = HtmlDocument.Parse """<html><head></head></html"""
let expected =
let expected =
HtmlDocument.New
[ HtmlNode.NewElement
("html",
[ HtmlNode.NewElement("head")])]
result |> should equal expected
result |> should equal expected