Skip to content

Commit 8a6a428

Browse files
committed
Use more EffectFn
1 parent 25a3695 commit 8a6a428

File tree

7 files changed

+250
-290
lines changed

7 files changed

+250
-290
lines changed

src/Halogen/VDom.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ module Halogen.VDom
44
, module Types
55
) where
66

7-
import Halogen.VDom.DOM (VDomMachine, VDomStep, VDomSpec(..), buildVDom) as DOM
7+
import Halogen.VDom.DOM (VDomSpec(..), buildVDom) as DOM
88
import Halogen.VDom.Machine (Machine, Step(..), extract, step, halt) as Machine
99
import Halogen.VDom.Types (VDom(..), Graft, runGraft, ElemSpec(..), ElemName(..), Namespace(..)) as Types

src/Halogen/VDom/DOM.purs

Lines changed: 132 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
module Halogen.VDom.DOM
2-
( VDomMachine
3-
, VDomStep
4-
, VDomSpec(..)
2+
( VDomSpec(..)
53
, buildVDom
64
, buildText
75
, buildElem
@@ -16,7 +14,7 @@ import Data.Function.Uncurried as Fn
1614
import Data.Maybe (Maybe(..))
1715
import Data.Nullable (toNullable)
1816
import Data.Tuple (Tuple(..), fst)
19-
import Effect (Effect, foreachE)
17+
import Effect (foreachE)
2018
import Effect.Uncurried as EFn
2119
import Halogen.VDom.Machine (Step(..), Machine)
2220
import Halogen.VDom.Machine as Machine
@@ -27,15 +25,21 @@ import Web.DOM.Element (Element) as DOM
2725
import Web.DOM.Element as DOMElement
2826
import Web.DOM.Node (Node) as DOM
2927

30-
type VDomMachine a b = Machine Effect a b
28+
type VDomMachine a w = Machine (VDom a w) DOM.Node
3129

32-
type VDomStep a b = Effect (Step Effect a b)
30+
type VDomStep a w = Step (VDom a w) DOM.Node
31+
32+
type VDomInit i a w = EFn.EffectFn1 i (VDomStep a w)
33+
34+
type VDomBuilder i a w = EFn.EffectFn3 (VDomSpec a w) (VDomMachine a w) i (VDomStep a w)
35+
36+
type VDomBuilder2 i j a w = EFn.EffectFn4 (VDomSpec a w) (VDomMachine a w) i j (VDomStep a w)
3337

3438
-- | Widget machines recursively reference the configured spec to potentially
3539
-- | enable recursive trees of Widgets.
3640
newtype VDomSpec a w = VDomSpec
37-
{ buildWidget VDomSpec a w VDomMachine w DOM.Node
38-
, buildAttributes DOM.Element VDomMachine a Unit
41+
{ buildWidget VDomSpec a w Machine w DOM.Node
42+
, buildAttributes DOM.Element Machine a Unit
3943
, document DOM.Document
4044
}
4145

@@ -48,179 +52,162 @@ newtype VDomSpec a w = VDomSpec
4852
-- | machine3 ← Machine.step machine2 vdomTree3
4953
-- | ...
5054
-- | ````
51-
buildVDom a w. VDomSpec a w VDomMachine (VDom a w) DOM.Node
52-
buildVDom spec = render
55+
buildVDom a w. VDomSpec a w VDomMachine a w
56+
buildVDom spec = build
5357
where
54-
render = case _ of
55-
Text s → buildText spec s
56-
Elem es ch → buildElem spec es ch
57-
Keyed es ch → buildKeyed spec es ch
58-
Widget w → buildWidget spec w
59-
Grafted g → buildVDom spec (runGraft g)
60-
61-
buildText a w. VDomSpec a w String VDomStep (VDom a w) DOM.Node
62-
buildText (VDomSpec spec) = render
58+
build = EFn.mkEffectFn1 case _ of
59+
Text s → EFn.runEffectFn3 buildText spec build s
60+
Elem es ch → EFn.runEffectFn4 buildElem spec build es ch
61+
Keyed es ch → EFn.runEffectFn4 buildKeyed spec build es ch
62+
Widget w → EFn.runEffectFn3 buildWidget spec build w
63+
Grafted g → EFn.runEffectFn1 build (runGraft g)
64+
65+
buildText a w. VDomBuilder String a w
66+
buildText = render
6367
where
64-
render s = do
68+
render = EFn.mkEffectFn3 \(VDomSpec spec) build s → do
6569
node ← EFn.runEffectFn2 Util.createTextNode s spec.document
66-
pure (Step node (Fn.runFn2 patch node s) (done node))
67-
68-
patch = Fn.mkFn2 \node s1 → case _ of
69-
Grafted g →
70-
Fn.runFn2 patch node s1 (runGraft g)
71-
Text s2 → do
72-
let res = Step node (Fn.runFn2 patch node s2) (done node)
73-
case s1 == s2 of
74-
true → pure res
75-
_ → do
76-
EFn.runEffectFn2 Util.setTextContent s2 node
77-
pure res
78-
vdom → do
79-
done node
80-
buildVDom (VDomSpec spec) vdom
70+
let halt = done node
71+
pure (Step node (Fn.runFn4 patch build halt node s) halt)
72+
73+
patch = Fn.mkFn4 \build halt node s1 →
74+
EFn.mkEffectFn1 case _ of
75+
Grafted g →
76+
EFn.runEffectFn1 (Fn.runFn4 patch build halt node s1) (runGraft g)
77+
Text s2 → do
78+
let res = Step node (Fn.runFn4 patch build halt node s2) halt
79+
if s1 == s2
80+
then pure res
81+
else do
82+
EFn.runEffectFn2 Util.setTextContent s2 node
83+
pure res
84+
vdom → do
85+
halt
86+
EFn.runEffectFn1 build vdom
8187

8288
done node = do
83-
parent ← pure (Util.unsafeParent node)
89+
parent ← EFn.runEffectFn1 Util.parentNode node
8490
EFn.runEffectFn2 Util.removeChild node parent
8591

86-
buildElem
87-
a w
88-
. VDomSpec a w
89-
ElemSpec a
90-
Array (VDom a w)
91-
VDomStep (VDom a w) DOM.Node
92-
buildElem (VDomSpec spec) = render
92+
buildElem a w. VDomBuilder2 (ElemSpec a) (Array (VDom a w)) a w
93+
buildElem = render
9394
where
94-
render es1@(ElemSpec ns1 name1 as1) ch1 = do
95+
render = EFn.mkEffectFn4 \(VDomSpec spec) build es1@(ElemSpec ns1 name1 as1) ch1 do
9596
el ← EFn.runEffectFn3 Util.createElement (toNullable ns1) name1 spec.document
9697
let
9798
node = DOMElement.toNode el
9899
onChild = EFn.mkEffectFn2 \ix child → do
99-
res@Step n m h ← buildVDom (VDomSpec spec) child
100+
res@Step n m h ← EFn.runEffectFn1 build child
100101
EFn.runEffectFn3 Util.insertChildIx ix n node
101102
pure res
102103
steps ← EFn.runEffectFn2 Util.forE ch1 onChild
103-
attrs ← spec.buildAttributes el as1
104-
pure
105-
(Step node
106-
(Fn.runFn4 patch node attrs es1 steps)
107-
(Fn.runFn3 done node attrs steps))
108-
109-
patch = Fn.mkFn4 \node attrs (es1@(ElemSpec ns1 name1 as1)) ch1 → case _ of
110-
Grafted g →
111-
Fn.runFn4 patch node attrs es1 ch1 (runGraft g)
112-
Elem es2@(ElemSpec ns2 name2 as2) ch2 | Fn.runFn2 eqElemSpec es1 es2 → do
113-
case Array.length ch1, Array.length ch2 of
114-
0, 0do
115-
attrs' ← Machine.step attrs as2
116-
pure
117-
(Step node
118-
(Fn.runFn4 patch node attrs' es2 ch1)
119-
(Fn.runFn3 done node attrs' ch1))
120-
_, _ → do
121-
let
122-
onThese = EFn.mkEffectFn3 \ix (prev@Step n step halt) vdom → do
123-
res@Step n' m' h' ← step vdom
124-
EFn.runEffectFn3 Util.insertChildIx ix n' node
125-
pure res
126-
onThis = EFn.mkEffectFn2 \ix (Step n _ halt) → halt
127-
onThat = EFn.mkEffectFn2 \ix vdom → do
128-
res@Step n m h ← buildVDom (VDomSpec spec) vdom
129-
EFn.runEffectFn3 Util.insertChildIx ix n node
130-
pure res
131-
steps ← EFn.runEffectFn5 Util.diffWithIxE ch1 ch2 onThese onThis onThat
132-
attrs' ← Machine.step attrs as2
133-
pure
134-
(Step node
135-
(Fn.runFn4 patch node attrs' es2 steps)
136-
(Fn.runFn3 done node attrs' steps))
137-
vdom → do
138-
Fn.runFn3 done node attrs ch1
139-
buildVDom (VDomSpec spec) vdom
104+
attrs ← EFn.runEffectFn1 (spec.buildAttributes el) as1
105+
let halt = Fn.runFn3 done node attrs steps
106+
pure (Step node (Fn.runFn6 patch build halt node attrs es1 steps) halt)
107+
108+
patch = Fn.mkFn6 \build halt node attrs (es1@(ElemSpec ns1 name1 as1)) ch1 →
109+
EFn.mkEffectFn1 case _ of
110+
Grafted g →
111+
EFn.runEffectFn1 (Fn.runFn6 patch build halt node attrs es1 ch1) (runGraft g)
112+
Elem es2@(ElemSpec ns2 name2 as2) ch2 | Fn.runFn2 eqElemSpec es1 es2 → do
113+
case Array.length ch1, Array.length ch2 of
114+
0, 0do
115+
attrs' ← EFn.runEffectFn1 (Machine.step attrs) as2
116+
let halt' = Fn.runFn3 done node attrs' ch1
117+
pure (Step node (Fn.runFn6 patch build halt' node attrs' es2 ch1) halt')
118+
_, _ → do
119+
let
120+
onThese = EFn.mkEffectFn3 \ix prev@(Step _ step _) vdom → do
121+
res@(Step n' _ _) ← EFn.runEffectFn1 step vdom
122+
EFn.runEffectFn3 Util.insertChildIx ix n' node
123+
pure res
124+
onThis = EFn.mkEffectFn2 \ix (Step _ _ h) → h
125+
onThat = EFn.mkEffectFn2 \ix vdom → do
126+
res@(Step n _ _) ← EFn.runEffectFn1 build vdom
127+
EFn.runEffectFn3 Util.insertChildIx ix n node
128+
pure res
129+
steps ← EFn.runEffectFn5 Util.diffWithIxE ch1 ch2 onThese onThis onThat
130+
attrs' ← EFn.runEffectFn1 (Machine.step attrs) as2
131+
let halt' = Fn.runFn3 done node attrs' steps
132+
pure (Step node (Fn.runFn6 patch build halt' node attrs' es2 steps) halt')
133+
vdom → do
134+
halt
135+
EFn.runEffectFn1 build vdom
140136

141137
done = Fn.mkFn3 \node attrs steps → do
142-
parent ← pure (Util.unsafeParent node)
138+
parent ← EFn.runEffectFn1 Util.parentNode node
143139
EFn.runEffectFn2 Util.removeChild node parent
144140
foreachE steps Machine.halt
145141
Machine.halt attrs
146142

147-
buildKeyed
148-
a w
149-
. VDomSpec a w
150-
ElemSpec a
151-
Array (Tuple String (VDom a w))
152-
VDomStep (VDom a w) DOM.Node
153-
buildKeyed (VDomSpec spec) = render
143+
buildKeyed a w. VDomBuilder2 (ElemSpec a) (Array (Tuple String (VDom a w))) a w
144+
buildKeyed = render
154145
where
155-
render es1@(ElemSpec ns1 name1 as1) ch1 = do
146+
render = EFn.mkEffectFn4 \(VDomSpec spec) build es1@(ElemSpec ns1 name1 as1) ch1 do
156147
el ← EFn.runEffectFn3 Util.createElement (toNullable ns1) name1 spec.document
157148
let
158149
node = DOMElement.toNode el
159150
onChild = EFn.mkEffectFn3 \k ix (Tuple _ vdom) → do
160-
res@Step n m hbuildVDom (VDomSpec spec) vdom
151+
res@(Step n _ _)EFn.runEffectFn1 build vdom
161152
EFn.runEffectFn3 Util.insertChildIx ix n node
162153
pure res
163154
steps ← EFn.runEffectFn3 Util.strMapWithIxE ch1 fst onChild
164-
attrs ← spec.buildAttributes el as1
165-
pure
166-
(Step node
167-
(Fn.runFn5 patch node attrs es1 steps (Array.length ch1))
168-
(Fn.runFn3 done node attrs steps))
169-
170-
patch = Fn.mkFn5 \node attrs (es1@(ElemSpec ns1 name1 as1)) ch1 len1 → case _ of
171-
Grafted g →
172-
Fn.runFn5 patch node attrs es1 ch1 len1 (runGraft g)
173-
Keyed es2@(ElemSpec ns2 name2 as2) ch2 | Fn.runFn2 eqElemSpec es1 es2 →
174-
case len1, Array.length ch2 of
175-
0, 0do
176-
attrs' ← Machine.step attrs as2
177-
pure
178-
(Step node
179-
(Fn.runFn5 patch node attrs' es2 ch1 0)
180-
(Fn.runFn3 done node attrs' ch1))
181-
_, len2 → do
182-
let
183-
onThese = EFn.mkEffectFn4 \k ix' (Step n step _) (Tuple _ vdom) → do
184-
res@Step n' m' h' ← step vdom
185-
EFn.runEffectFn3 Util.insertChildIx ix' n' node
186-
pure res
187-
onThis = EFn.mkEffectFn2 \k (Step n _ halt) → halt
188-
onThat = EFn.mkEffectFn3 \k ix (Tuple _ vdom) → do
189-
res@Step n' m' h' ← buildVDom (VDomSpec spec) vdom
190-
EFn.runEffectFn3 Util.insertChildIx ix n' node
191-
pure res
192-
steps ← EFn.runEffectFn6 Util.diffWithKeyAndIxE ch1 ch2 fst onThese onThis onThat
193-
attrs' ← Machine.step attrs as2
194-
pure
195-
(Step node
196-
(Fn.runFn5 patch node attrs' es2 steps len2)
197-
(Fn.runFn3 done node attrs' steps))
198-
vdom → do
199-
Fn.runFn3 done node attrs ch1
200-
buildVDom (VDomSpec spec) vdom
155+
attrs ← EFn.runEffectFn1 (spec.buildAttributes el) as1
156+
let halt = Fn.runFn3 done node attrs steps
157+
pure (Step node (Fn.runFn7 patch build halt node attrs es1 steps (Array.length ch1)) halt)
158+
159+
patch = Fn.mkFn7 \build halt node attrs (es1@(ElemSpec ns1 name1 as1)) ch1 len1 →
160+
EFn.mkEffectFn1 case _ of
161+
Grafted g →
162+
EFn.runEffectFn1 (Fn.runFn7 patch build halt node attrs es1 ch1 len1) (runGraft g)
163+
Keyed es2@(ElemSpec ns2 name2 as2) ch2 | Fn.runFn2 eqElemSpec es1 es2 →
164+
case len1, Array.length ch2 of
165+
0, 0do
166+
attrs' ← EFn.runEffectFn1 (Machine.step attrs) as2
167+
let halt' = Fn.runFn3 done node attrs' ch1
168+
pure (Step node (Fn.runFn7 patch build halt' node attrs' es2 ch1 0) halt')
169+
_, len2 → do
170+
let
171+
onThese = EFn.mkEffectFn4 \_ ix' (Step _ step _) (Tuple _ vdom) → do
172+
res@(Step n' _ _) ← EFn.runEffectFn1 step vdom
173+
EFn.runEffectFn3 Util.insertChildIx ix' n' node
174+
pure res
175+
onThis = EFn.mkEffectFn2 \_ (Step _ _ h) → h
176+
onThat = EFn.mkEffectFn3 \_ ix (Tuple _ vdom) → do
177+
res@(Step n' _ _) ← EFn.runEffectFn1 build vdom
178+
EFn.runEffectFn3 Util.insertChildIx ix n' node
179+
pure res
180+
steps ← EFn.runEffectFn6 Util.diffWithKeyAndIxE ch1 ch2 fst onThese onThis onThat
181+
attrs' ← EFn.runEffectFn1 (Machine.step attrs) as2
182+
let halt' = Fn.runFn3 done node attrs' steps
183+
pure (Step node (Fn.runFn7 patch build halt' node attrs' es2 steps len2) halt')
184+
vdom → do
185+
halt
186+
EFn.runEffectFn1 build vdom
201187

202188
done = Fn.mkFn3 \node attrs steps → do
203-
parent ← pure (Util.unsafeParent node)
189+
parent ← EFn.runEffectFn1 Util.parentNode node
204190
EFn.runEffectFn2 Util.removeChild node parent
205191
EFn.runEffectFn2 Util.forInE steps (EFn.mkEffectFn2 \_ (Step _ _ halt) → halt)
206192
Machine.halt attrs
207193

208-
buildWidget a w. VDomSpec a w w VDomStep (VDom a w) DOM.Node
209-
buildWidget (VDomSpec spec) = render
194+
buildWidget a w. VDomBuilder w a w
195+
buildWidget = render
210196
where
211-
render w = do
212-
res@Step n m h ← spec.buildWidget (VDomSpec spec) w
213-
pure (Step n (patch res) h)
214-
215-
patch prev@(Step node step halt) = case _ of
216-
Grafted g →
217-
patch prev (runGraft g)
218-
Widget w → do
219-
res@Step n m h ← step w
220-
pure (Step n (patch res) h)
221-
vdom → do
222-
halt
223-
buildVDom (VDomSpec spec) vdom
197+
render = EFn.mkEffectFn3 \(VDomSpec spec) build w → do
198+
res@(Step n _ h) ← EFn.runEffectFn1 (spec.buildWidget (VDomSpec spec)) w
199+
pure (Step n (Fn.runFn2 patch build res) h)
200+
201+
patch = Fn.mkFn2 \build prev@(Step node step halt) →
202+
EFn.mkEffectFn1 case _ of
203+
Grafted g →
204+
EFn.runEffectFn1 (Fn.runFn2 patch build prev) (runGraft g)
205+
Widget w → do
206+
res@(Step n _ h) ← EFn.runEffectFn1 step w
207+
pure (Step n (Fn.runFn2 patch build res) h)
208+
vdom → do
209+
halt
210+
EFn.runEffectFn1 build vdom
224211

225212
eqElemSpec a. Fn.Fn2 (ElemSpec a) (ElemSpec a) Boolean
226213
eqElemSpec = Fn.mkFn2 \a b →

0 commit comments

Comments
 (0)