@@ -2,19 +2,19 @@ module Test.Main where
2
2
3
3
import Prelude
4
4
5
- import Data.Exists ( Exists , mkExists )
5
+ import Data.Bifunctor ( bimap )
6
6
import Data.Foldable (for_ , traverse_ )
7
7
import Data.Function.Uncurried as Fn
8
8
import Data.Maybe (Maybe (..), isNothing )
9
- import Data.Newtype (wrap )
9
+ import Data.Newtype (class Newtype , un , wrap )
10
10
import Data.Tuple (Tuple (..))
11
11
import Effect (Effect )
12
12
import Effect.Ref as Ref
13
13
import Effect.Timer as Timer
14
14
import Effect.Uncurried as EFn
15
15
import Halogen.VDom as V
16
16
import Halogen.VDom.DOM.Prop (Prop (..), propFromString , buildProp )
17
- import Halogen.VDom.Util ( refEq )
17
+ import Halogen.VDom.Thunk ( Thunk , thunk1 , buildThunk )
18
18
import Unsafe.Coerce (unsafeCoerce )
19
19
import Web.DOM.Document (Document ) as DOM
20
20
import Web.DOM.Element (toNode ) as DOM
@@ -29,9 +29,12 @@ infixr 1 prop as :=
29
29
prop ∷ ∀ a . String → String → Prop a
30
30
prop key val = Property key (propFromString val)
31
31
32
- type VDom = V.VDom (Array (Prop Void )) (Exists Thunk )
32
+ newtype VDom a = VDom ( V.VDom (Array (Prop a )) (Thunk VDom a ) )
33
33
34
- data Thunk b = Thunk b (b → VDom )
34
+ instance functorHtml ∷ Functor VDom where
35
+ map f (VDom vdom) = VDom (bimap (map (map f)) (map f) vdom)
36
+
37
+ derive instance newtypeVDom ∷ Newtype (VDom a ) _
35
38
36
39
type State = Array Database
37
40
@@ -55,19 +58,19 @@ type DBQuery =
55
58
initialState ∷ State
56
59
initialState = []
57
60
58
- elem ∷ ∀ a w . String → a → Array (V. VDom a w ) → V. VDom a w
59
- elem n a = V.Elem Nothing (V.ElemName n) a
61
+ elem ∷ ∀ a . String → Array ( Prop a ) → Array (VDom a ) → VDom a
62
+ elem n a c = VDom $ V.Elem Nothing (V.ElemName n) a (unsafeCoerce c)
60
63
61
- keyed ∷ ∀ a w . String → a → Array (Tuple String (V. VDom a w )) → V. VDom a w
62
- keyed n a = V.Keyed Nothing (V.ElemName n) a
64
+ keyed ∷ ∀ a . String → Array ( Prop a ) → Array (Tuple String (VDom a )) → VDom a
65
+ keyed n a c = VDom $ V.Keyed Nothing (V.ElemName n) a (unsafeCoerce c)
63
66
64
- text ∷ ∀ a w . String → V. VDom a w
65
- text = V.Text
67
+ text ∷ ∀ a . String → VDom a
68
+ text a = VDom $ V.Text a
66
69
67
- thunk ∷ ∀ a . (a → VDom ) → a → VDom
68
- thunk render val = V.Widget (mkExists ( Thunk val render))
70
+ thunk ∷ ∀ a b . (a → VDom b ) → a → VDom b
71
+ thunk render val = VDom $ V.Widget $ Fn .runFn2 thunk1 render val
69
72
70
- renderData ∷ State → VDom
73
+ renderData ∷ State → VDom Void
71
74
renderData st =
72
75
elem " div" []
73
76
[ elem " table"
@@ -108,41 +111,11 @@ renderData st =
108
111
]
109
112
]
110
113
111
- type WidgetState a w =
112
- { t :: Exists Thunk
113
- , step :: V.Step a w
114
- }
115
-
116
- buildWidget
117
- ∷ V.VDomSpec (Array (Prop Void )) (Exists Thunk )
118
- → V.Machine (Exists Thunk ) DOM.Node
119
- buildWidget spec = render
120
- where
121
- render = EFn .mkEffectFn1 \t → case unsafeCoerce t of
122
- Thunk a render' → do
123
- step ← EFn .runEffectFn1 (V .buildVDom spec) (render' a)
124
- let state = { t, step }
125
- pure (V .mkStep (V.Step (V .extract step) state patch done))
126
-
127
- patch = EFn .mkEffectFn2 \state t →
128
- case unsafeCoerce state.t, unsafeCoerce t of
129
- Thunk a render1, Thunk b render2 →
130
- if Fn .runFn2 refEq a b && Fn .runFn2 refEq render1 render2
131
- then
132
- pure (V .mkStep (V.Step (V .extract state.step) state patch done))
133
- else do
134
- step ← EFn .runEffectFn2 V .step state.step (render2 b)
135
- let nextState = { t, step }
136
- pure (V .mkStep (V.Step (V .extract step) nextState patch done))
137
-
138
- done = EFn .mkEffectFn1 \state → do
139
- EFn .runEffectFn1 V .halt state.step
140
-
141
114
mkSpec
142
115
∷ DOM.Document
143
- → V.VDomSpec (Array (Prop Void )) (Exists Thunk )
116
+ → V.VDomSpec (Array (Prop Void )) (Thunk VDom Void )
144
117
mkSpec document = V.VDomSpec
145
- { buildWidget
118
+ { buildWidget: buildThunk (un VDom )
146
119
, buildAttributes: buildProp (const (pure unit))
147
120
, document
148
121
}
@@ -157,13 +130,13 @@ foreign import requestAnimationFrame ∷ Effect Unit → Effect Unit
157
130
158
131
mkRenderQueue
159
132
∷ ∀ a
160
- . V.VDomSpec (Array (Prop Void )) (Exists Thunk )
133
+ . V.VDomSpec (Array (Prop Void )) (Thunk VDom Void )
161
134
→ DOM.Node
162
- → (a → VDom )
135
+ → (a → VDom Void )
163
136
→ a
164
137
→ Effect (a → Effect Unit )
165
138
mkRenderQueue spec parent render initialValue = do
166
- initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (render initialValue)
139
+ initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (un VDom ( render initialValue) )
167
140
_ ← DOM .appendChild (V .extract initMachine) parent
168
141
ref ← Ref .new initMachine
169
142
val ← Ref .new Nothing
@@ -173,24 +146,24 @@ mkRenderQueue spec parent render initialValue = do
173
146
when (isNothing v) $ requestAnimationFrame do
174
147
machine ← Ref .read ref
175
148
Ref .read val >>= traverse_ \v' → do
176
- res ← EFn .runEffectFn2 V .step machine (render v')
149
+ res ← EFn .runEffectFn2 V .step machine (un VDom ( render v') )
177
150
Ref .write res ref
178
151
Ref .write Nothing val
179
152
180
153
mkRenderQueue'
181
154
∷ ∀ a
182
- . V.VDomSpec (Array (Prop Void )) (Exists Thunk )
155
+ . V.VDomSpec (Array (Prop Void )) (Thunk VDom Void )
183
156
→ DOM.Node
184
- → (a → VDom )
157
+ → (a → VDom Void )
185
158
→ a
186
159
→ Effect (a → Effect Unit )
187
160
mkRenderQueue' spec parent render initialValue = do
188
- initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (render initialValue)
161
+ initMachine ← EFn .runEffectFn1 (V .buildVDom spec) (un VDom ( render initialValue) )
189
162
_ ← DOM .appendChild (V .extract initMachine) parent
190
163
ref ← Ref .new initMachine
191
164
pure \v → do
192
165
machine ← Ref .read ref
193
- res ← EFn .runEffectFn2 V .step machine (render v)
166
+ res ← EFn .runEffectFn2 V .step machine (un VDom ( render v) )
194
167
Ref .write res ref
195
168
196
169
main ∷ Effect Unit
0 commit comments