Skip to content

Commit

Permalink
Improvements to the XmlViewEngine to allow boolean attributes such as…
Browse files Browse the repository at this point in the history
… `async` or `defer` on script tags.
  • Loading branch information
dustinmoris committed Jul 22, 2017
1 parent c8492b3 commit cc1baeb
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/Giraffe/Giraffe.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<AssemblyName>Giraffe</AssemblyName>
<Version>0.1.0-alpha024</Version>
<Version>0.1.0-alpha025</Version>
<Description>A native functional ASP.NET Core web framework for F# developers.</Description>
<Copyright>Copyright 2017 Dustin Moris Gorski</Copyright>
<NeutralLanguage>en-GB</NeutralLanguage>
Expand Down
19 changes: 14 additions & 5 deletions src/Giraffe/XmlViewEngine.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ open System.Net
/// - https://www.w3.org/TR/html5/syntax.html#void-elements
/// ---------------------------
type XmlAttribute = string * string // Key * Value
type XmlAttribute =
| KeyValue of string * string
| Boolean of string

type XmlElement = string * XmlAttribute[] // Name * XML attributes

type XmlNode =
Expand All @@ -40,6 +43,9 @@ type XmlNode =
/// Building blocks
/// ---------------------------
let attr (key : string) (value : string) = KeyValue (key, value)
let flag (key : string) = Boolean key

let tag (tagName : string)
(attributes : XmlAttribute list)
(contents : XmlNode list) =
Expand Down Expand Up @@ -195,19 +201,22 @@ let summary = tag "summary"
/// ---------------------------
let rec private nodeToString (htmlStyle : bool) (node : XmlNode) =
let startElementToString selfClosing (elemName, attributes) =
let closingBracket =
let startElementToString selfClosing (elemName, attributes : XmlAttribute array) =
let closingBracket =
match selfClosing with
| false -> ">"
| true ->
match htmlStyle with
| false -> " />"
| true -> ">"
| true -> ">"
match attributes with
| [||] -> sprintf "<%s%s" elemName closingBracket
| _ ->
attributes
|> Array.map (fun (k, v) -> sprintf " %s=\"%s\"" k (WebUtility.HtmlEncode v))
|> Array.map (fun attr ->
match attr with
| KeyValue (k, v) -> sprintf " %s=\"%s\"" k (WebUtility.HtmlEncode v)
| Boolean k -> sprintf " %s" k)
|> String.Concat
|> sprintf "<%s%s%s" elemName
<| closingBracket
Expand Down
13 changes: 10 additions & 3 deletions tests/Giraffe.Tests/XmlViewEngineTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,25 @@ let removeNewLines (html:string):string =
let ``Single html root should compile`` () =
let doc = html [] []
let html =
doc
doc
|> renderHtmlDocument
|> removeNewLines
Assert.Equal("<!DOCTYPE html><html></html>", html)

[<Fact>]
let ``Anchor should contain href, target and content`` () =
let anchor =
a [ "href", "http://example.org"; "target", "_blank" ] [ encodedText "Example" ]
a [ attr "href" "http://example.org"; attr "target" "_blank" ] [ encodedText "Example" ]
let html = renderXmlNode anchor
Assert.Equal("<a href=\"http://example.org\" target=\"_blank\">Example</a>", html)

[<Fact>]
let ``Script should contain src, lang and async`` () =
let scriptFile =
script [ attr "src" "http://example.org/example.js"; attr "lang" "javascript"; flag "async" ] []
let html = renderXmlNode scriptFile
Assert.Equal("<script src=\"http://example.org/example.js\" lang=\"javascript\" async></script>", html)

[<Fact>]
let ``Nested content should render correctly`` () =
let nested =
Expand All @@ -34,7 +41,7 @@ let ``Nested content should render correctly`` () =
strong [] [ encodedText "Ipsum" ]
RawText " dollar"
] ]
let html =
let html =
nested
|> renderXmlNode
|> removeNewLines
Expand Down

0 comments on commit cc1baeb

Please sign in to comment.