// [snippet:Implementation]
// We need to disable some warnings, because the programming style is a bit tricky
#nowarn "686" // specifying type parameters explicitly for createElement
#nowarn "20" // ignoring returned value
#r "System.Xml.Linq.dll"
open System.Xml.Linq
open System.Collections.Generic
let xn s = XName.Get(s)
// Various types of HTML elements are represented as classes
// This is used only for specifying content templates for
// placeholders when creating parameterized views
// See also: 'h.content' in the last example
type ContentTemplate() =
member x.Zero() = ()
member x.Delay(f : unit -> unit) = f
// This represents any HTML element that we're creating
// HTML elements that do not allow content (e.g. , )
// should inherit from this type
type Element() =
let mutable name : string = ""
let mutable pg : Page = Unchecked.defaultof<_>
let mutable el : XElement = null
member x.Page = pg
member x.Init(n, p, e) =
name <- n; pg <- p; el <- e
member x.AddAttr n v =
el.Add(XAttribute(xn n, v))
// Represents HTML element with default attributes (id, style, class)
and ElementDef() =
inherit Element()
member x.set(?id:string, ?style:string, ?cssclass:string) =
id |> Option.iter (x.AddAttr "id")
style |> Option.iter (x.AddAttr "style")
cssclass |> Option.iter (x.AddAttr "class")
// Represents HTML element with some other required attributes
and ElementLink() =
inherit Element()
member x.set(rel:string, href:string, typ:string, ?id:string, ?style:string, ?cssclass:string) =
x.AddAttr "rel" rel
x.AddAttr "href" href
x.AddAttr "type" typ
id |> Option.iter (x.AddAttr "id")
style |> Option.iter (x.AddAttr "style")
cssclass |> Option.iter (x.AddAttr "class")
// TODO: We need to add other types of HTML elements...
// This represents HTML element that can contain some other elements (e.g.