Skip to content

Commit 200e5bc

Browse files
committed
WIP
1 parent 7b345ce commit 200e5bc

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

bower.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "purescript-halogen-vdom-string-renderer",
3+
"ignore": [
4+
"**/.*",
5+
"node_modules",
6+
"bower_components",
7+
"output"
8+
],
9+
"dependencies": {
10+
"purescript-prelude": "^2.3.0",
11+
"purescript-console": "^2.0.0",
12+
"purescript-halogen-vdom": "^1.0.1"
13+
},
14+
"devDependencies": {
15+
"purescript-psci-support": "^2.0.0"
16+
}
17+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Halogen.VDom.DOM.StringRenderer where
2+
3+
import Prelude
4+
import Halogen.VDom (VDom(..), ElemSpec(..), ElemName(..), Namespace(..), runGraft)
5+
import Halogen.VDom.DOM.Prop (Prop(..))
6+
import Data.Tuple (snd)
7+
import Data.String as S
8+
import Data.Maybe (maybe)
9+
import Data.Array as A
10+
import Data.Foldable as F
11+
import Halogen.VDom.StringRenderer as VSR
12+
13+
14+
render i w. (w String) VDom (Array (Prop i)) w String
15+
render renderWidget = VSR.render getTagType renderProps renderWidget
16+
where
17+
getTagType :: ElemName -> VSR.TagType
18+
getTagType en
19+
| F.elem en voidElements = VSR.SelfClosingTag
20+
| otherwise = VSR.NormalTag
21+
renderProps :: Array (Prop i) -> String
22+
renderProps = S.joinWith " " <<< A.mapMaybe renderProp
23+
renderProp :: Prop i -> Maybe String
24+
renderProp = case _ of
25+
Attribute (Maybe Namespace) String String
26+
Property String PropValue
27+
Handler _ _ → Nothing
28+
Ref _ → Nothing
29+
30+
voidElements :: Array ElemName
31+
voidElements =
32+
[ ElemName "area"
33+
, ElemName "base"
34+
, ElemName "br"
35+
, ElemName "col"
36+
, ElemName "embed"
37+
, ElemName "hr"
38+
, ElemName "img"
39+
, ElemName "input"
40+
, ElemName "isindex" -- legacy XHTML
41+
, ElemName "keygen"
42+
, ElemName "link"
43+
, ElemName "meta"
44+
, ElemName "param"
45+
, ElemName "source"
46+
, ElemName "track"
47+
, ElemName "wbr"
48+
]

src/Halogen/VDom/StringRenderer.purs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Halogen.VDom.StringRenderer where
2+
3+
import Prelude
4+
5+
import Data.Array as A
6+
import Data.Maybe (maybe)
7+
import Data.String as S
8+
import Data.Tuple (snd)
9+
10+
import Halogen.VDom (VDom(..), ElemSpec(..), ElemName(..), Namespace(..), runGraft)
11+
12+
-- | Type used to determine whether an element can be rendered as self-closing
13+
-- | element, for example, "<br/>".
14+
data TagType
15+
= NormalTag
16+
| SelfClosingTag
17+
18+
derive instance eqTagTypeEq TagType
19+
derive instance ordTagTypeOrd TagType
20+
21+
-- | Renders a `VDom` tree to a string using the specified tag type scheme,
22+
-- | attribute renderer, and widget renderer.
23+
render
24+
a w
25+
. (ElemName TagType)
26+
(a String)
27+
(w String)
28+
VDom a w
29+
String
30+
render getTagType renderAttrs renderWidget = go
31+
where
32+
go VDom a w String
33+
go = case _ of
34+
Text s → s
35+
Elem elem children → renderElement elem children
36+
Keyed elem kchildren → renderElement elem (map snd kchildren)
37+
Widget w → renderWidget w
38+
Grafted g → go (runGraft g)
39+
renderElement ElemSpec a Array (VDom a w) String
40+
renderElement (ElemSpec mns en@(ElemName name) attrs) children =
41+
let
42+
as = renderAttrs attrs
43+
as' = maybe as (\(Namespace ns) -> "xmlns=\"" <> ns <> "\"" <> if S.null as then "" else " " <> as) mns
44+
in
45+
"<" <> name <> if S.null as then "" else " " <> as <>
46+
if A.null children
47+
then if getTagType en == SelfClosingTag then "/>" else "</" <> name <> ">"
48+
else ">" <> S.joinWith "" (map go children) <> "</" <> name <> ">"

0 commit comments

Comments
 (0)