@@ -21,12 +21,12 @@ import Control.Monad.Reader hiding (mapM, mapM_, forM, forM_, sequence, sequence
2121import Control.Monad.State hiding (state, mapM, mapM_, forM, forM_, sequence, sequence_)
2222import GHCJS.DOM.Node
2323import GHCJS.DOM.UIEvent
24−import GHCJS.DOM.EventM (event, EventM, stopPropagation)
24+import GHCJS.DOM.EventM (on, event, EventM, stopPropagation)
2525import GHCJS.DOM.Document
26−import GHCJS.DOM.Element
27−import GHCJS.DOM.HTMLElement
28−import GHCJS.DOM.Types hiding (Widget (..), unWidget, Event)
29−import GHCJS.DOM.NamedNodeMap
26+import GHCJS.DOM.Element as E
27+import GHCJS.DOM.Types hiding (Event)
28+import qualified GHCJS.DOM.Types as DOM (Event)
29+import GHCJS.DOM.NamedNodeMap as NNM
3030import Control.Lens hiding (element, children)
3131import Data.These
3232import Data.Align
@@ -60,27 +60,27 @@ class Attributes m a where
6060 addAttributes :: IsElement e => a -> e -> m ()
6161
6262instance MonadIO m => Attributes m AttributeMap where
63− addAttributes curAttrs e = liftIO $ imapM_ (elementSetAttribute e) curAttrs
63+ addAttributes curAttrs e = imapM_ (setAttribute e) curAttrs
6464
6565instance MonadWidget t m => Attributes m (Dynamic t AttributeMap) where
6666 addAttributes attrs e = do
6767 schedulePostBuild $ do
6868 curAttrs <- sample $ current attrs
69− liftIO $ imapM_ (elementSetAttribute e) curAttrs
69+ imapM_ (setAttribute e) curAttrs
7070 addVoidAction $ flip fmap (updated attrs) $ \newAttrs -> liftIO $ do
71− oldAttrs <- maybe (return Set.empty) namedNodeMapGetNames =<< elementGetAttributes e
72− forM_ (Set.toList $ oldAttrs `Set.difference` Map.keysSet newAttrs) $ elementRemoveAttribute e
73− imapM_ (elementSetAttribute e) newAttrs --TODO: avoid re-setting unchanged attributes; possibly do the compare using Align in haskell
71+ oldAttrs <- maybe (return Set.empty) namedNodeMapGetNames =<< getAttributes e
72+ forM_ (Set.toList $ oldAttrs `Set.difference` Map.keysSet newAttrs) $ removeAttribute e
73+ imapM_ (setAttribute e) newAttrs --TODO: avoid re-setting unchanged attributes; possibly do the compare using Align in haskell
7474
7575buildEmptyElementNS :: (MonadWidget t m, Attributes m attrs) => Maybe String -> String -> attrs -> m Element
7676buildEmptyElementNS mns elementTag attrs = do
7777 doc <- askDocument
7878 p <- askParent
7979 Just e <- liftIO $ case mns of
80− Nothing -> documentCreateElement doc elementTag
81− Just ns -> documentCreateElementNS doc ns elementTag
80+ Nothing -> createElement doc (Just elementTag)
81+ Just ns -> createElementNS doc (Just ns) (Just elementTag)
8282 addAttributes attrs e
83− _ <- liftIO $ nodeAppendChild p $ Just e
83+ _ <- appendChild p $ Just e
8484 return $ castToElement e
8585
8686buildEmptyElement :: (MonadWidget t m, Attributes m attrs) => String -> attrs -> m Element
@@ -96,13 +96,13 @@ buildElementNS mns elementTag attrs child = do
9696buildElement :: (MonadWidget t m, Attributes m attrs) => String -> attrs -> m a -> m (Element, a)
9797buildElement = buildElementNS Nothing
9898
99−namedNodeMapGetNames :: IsNamedNodeMap self => self -> IO (Set String)
99+namedNodeMapGetNames :: NamedNodeMap -> IO (Set String)
100100namedNodeMapGetNames self = do
101− l <- namedNodeMapGetLength self
101+ l <- NNM.getLength self
102102 let locations = if l == 0 then [] else [0..l-1] -- Can't use 0..l-1 if l is 0 because l is unsigned and will wrap around
103− liftM Set.fromList $ forM locations $ \i -> do
104− Just n <- namedNodeMapItem self i
105− nodeGetNodeName n
103+ liftM (Set.fromList . catMaybes) $ forM locations $ \i -> do
104+ Just n <- NNM.item self i
105+ getNodeName n
106106
107107text :: MonadWidget t m => String -> m ()
108108text = void . text'
@@ -112,8 +112,8 @@ text' :: MonadWidget t m => String -> m Text
112112text' s = do
113113 doc <- askDocument
114114 p <- askParent
115− Just n <- liftIO $ documentCreateTextNode doc s
116− _ <- liftIO $ nodeAppendChild p $ Just n
115+ Just n <- createTextNode doc s
116+ _ <- appendChild p $ Just n
117117 return n
118118
119119dynText :: MonadWidget t m => Dynamic t String -> m ()
@@ -121,8 +121,8 @@ dynText s = do
121121 n <- text' ""
122122 schedulePostBuild $ do
123123 curS <- sample $ current s
124− liftIO $ nodeSetNodeValue n curS
125− addVoidAction $ fmap (liftIO . nodeSetNodeValue n) $ updated s
124+ setNodeValue n $ Just curS
125+ addVoidAction $ fmap (setNodeValue n . Just) $ updated s
126126
127127display :: (MonadWidget t m, Show a) => Dynamic t a -> m ()
128128display a = dynText =<< mapDyn show a
@@ -130,7 +130,7 @@ display a = dynText =<< mapDyn show a
130130--TODO: Should this be renamed to 'widgetView' for consistency with 'widgetHold'?
131131-- | Given a Dynamic of widget-creating actions, create a widget that is recreated whenever the Dynamic updates.
132132-- The returned Event of widget results occurs when the Dynamic does.
133−-- Note: Often, the type 'a' is an Event, in which case the return value is an Event-of-Events that would typically be flattened.
133+-- Note: Often, the type 'a' is an Event, in which case the return value is an Event-of-Events that would typically be flattened (via 'switchPromptly').
134134dyn :: MonadWidget t m => Dynamic t (m a) -> m (Event t a)
135135dyn child = do
136136 postBuild <- getPostBuild
@@ -158,17 +158,15 @@ widgetHoldInternal child0 newChild = do
158158 tellWidgetOutput childOutput
159159 doc <- askDocument
160160 runWidget <- getRunWidget
161− let build c = do
162− Just df <- liftIO $ documentCreateDocumentFragment doc
163− (result, postBuild, voidActions) <- runWidget df c
164− runFrameWithTriggerRef newChildBuiltTriggerRef (result, voidActions)
165− postBuild
166− mp' <- liftIO $ nodeGetParentNode endPlaceholder
167− forM_ mp' $ \p' -> liftIO $ nodeInsertBefore p' (Just df) (Just endPlaceholder)
168− return ()
169161 addVoidAction $ ffor newChild $ \c -> do
162+ Just df <- createDocumentFragment doc
163+ (result, postBuild, voidActions) <- runWidget df c
164+ runFrameWithTriggerRef newChildBuiltTriggerRef (result, voidActions)
165+ postBuild
170166 liftIO $ deleteBetweenExclusive startPlaceholder endPlaceholder
171− build c
167+ mp' <- getParentNode endPlaceholder
168+ forM_ mp' $ \p' -> insertBefore p' (Just df) (Just endPlaceholder)
169+ return ()
172170 return (result0, fmap fst newChildBuilt)
173171
174172diffMapNoEq :: (Ord k) => Map k v -> Map k v -> Map k (Maybe v)
@@ -209,7 +207,7 @@ listWithKeyShallowDiff initialVals valsChanged mkChild = do
209207 Nothing -> Just Nothing -- Even if we let a Nothing through when the element doesn't already exist, this doesn't cause a problem because it is ignored
210208 Just _ -> Nothing -- We don't want to let spurious re-creations of items through
211209 listHoldWithKey initialVals (attachWith (flip (Map.differenceWith relevantDiff)) (current sentVals) valsChanged) $ \k v ->
212− mkChild k v $ select childValChangedSelector $ Const2 k
210+ mkChild k v $ Reflex.select childValChangedSelector $ Const2 k
213211
214212-- | Display the given map of items using the builder function provided, and update it with the given event. 'Nothing' entries will delete the corresponding children, and 'Just' entries will create or replace them. Since child events do not take any signal arguments, they are always rebuilt. To update a child without rebuilding, either embed signals in the map's values, or refer to them directly in the builder function.
215213listHoldWithKey :: (Ord k, MonadWidget t m) => Map k v -> Event t (Map k (Maybe v)) -> (k -> v -> m a) -> m (Dynamic t (Map k a))
@@ -224,13 +222,13 @@ listHoldWithKey initialVals valsChanged mkChild = do
224222 result <- mkChild k v
225223 childEnd <- text' ""
226224 return (result, (childStart, childEnd))
227− Just dfOrig <- liftIO $ documentCreateDocumentFragment doc
225+ Just dfOrig <- createDocumentFragment doc
228226 initialState <- iforM initialVals $ \k v -> subWidgetWithVoidActions (toNode dfOrig) $ wrapChild k v --Note: we have to use subWidgetWithVoidActions rather than runWidget here, because running post-build actions during build can cause not-yet-constructed values to be read
229227 stateRef <- liftIO $ newIORef initialState
230228 children <- holdDyn initialState newChildren
231229 tellWidgetOutput =<< mapDyn (fmap snd) children
232− mpOrig <- liftIO $ nodeGetParentNode endPlaceholder
233− forM_ mpOrig $ \pOrig -> liftIO $ nodeInsertBefore pOrig (Just dfOrig) (Just endPlaceholder)
230+ mpOrig <- liftIO $ getParentNode endPlaceholder
231+ forM_ mpOrig $ \pOrig -> liftIO $ insertBefore pOrig (Just dfOrig) (Just endPlaceholder)
234232 addVoidAction $ flip fmap valsChanged $ \newVals -> do
235233 curState <- liftIO $ readIORef stateRef
236234 --TODO: Should we remove the parent from the DOM first to avoid reflows?
@@ -240,24 +238,24 @@ listHoldWithKey initialVals valsChanged mkChild = do
240238 return Nothing
241239 These ((_, (start, end)), _) (Just v) -> do -- Replacing existing child
242240 liftIO $ deleteBetweenExclusive start end
243− Just df <- liftIO $ documentCreateDocumentFragment doc
241+ Just df <- createDocumentFragment doc
244242 (childResult, childPostBuild, childVoidAction) <- lift $ buildChild df k v
245243 let s = (childResult, childVoidAction)
246244 modify (>>childPostBuild)
247− mp <- liftIO $ nodeGetParentNode end
248− forM_ mp $ \p -> liftIO $ nodeInsertBefore p (Just df) (Just end)
245+ mp <- getParentNode end
246+ forM_ mp $ \p -> insertBefore p (Just df) (Just end)
249247 return $ Just s
250248 That Nothing -> return Nothing -- Deleting non-existent child
251249 That (Just v) -> do -- Creating new child
252− Just df <- liftIO $ documentCreateDocumentFragment doc
250+ Just df <- createDocumentFragment doc
253251 (childResult, childPostBuild, childVoidAction) <- lift $ buildChild df k v
254252 let s = (childResult, childVoidAction)
255253 modify (>>childPostBuild)
256254 let placeholder = case Map.lookupGT k curState of
257255 Nothing -> endPlaceholder
258256 Just (_, ((_, (start, _)), _)) -> start
259− mp <- liftIO $ nodeGetParentNode placeholder
260− forM_ mp $ \p -> liftIO $ nodeInsertBefore p (Just df) (Just placeholder)
257+ mp <- getParentNode placeholder
258+ forM_ mp $ \p -> insertBefore p (Just df) (Just placeholder)
261259 return $ Just s
262260 This state -> do -- No change
263261 return $ Just state
@@ -303,47 +301,56 @@ selectViewListWithKey_ selection vals mkChild = liftM (fmap fst) $ selectViewLis
303301-- | s and e must both be children of the same node and s must precede e
304302deleteBetweenExclusive :: (IsNode start, IsNode end) => start -> end -> IO ()
305303deleteBetweenExclusive s e = do
306− mCurrentParent <- nodeGetParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
304+ mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
307305 case mCurrentParent of
308306 Nothing -> return () --TODO: Is this the right behavior?
309307 Just currentParent -> do
310308 let go = do
311− Just x <- nodeGetPreviousSibling e -- This can't be Nothing because we should hit 's' first
309+ Just x <- getPreviousSibling e -- This can't be Nothing because we should hit 's' first
312310 when (toNode s /= toNode x) $ do
313− _ <- nodeRemoveChild currentParent $ Just x
311+ _ <- removeChild currentParent $ Just x
314312 go
315313 go
316314
317315-- | s and e must both be children of the same node and s must precede e
318316deleteBetweenInclusive :: (IsNode start, IsNode end) => start -> end -> IO ()
319317deleteBetweenInclusive s e = do
320− mCurrentParent <- nodeGetParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
318+ mCurrentParent <- getParentNode e -- May be different than it was at initial construction, e.g., because the parent may have dumped us in from a DocumentFragment
321319 case mCurrentParent of
322320 Nothing -> return () --TODO: Is this the right behavior?
323321 Just currentParent -> do
324322 let go = do
325− Just x <- nodeGetPreviousSibling e -- This can't be Nothing because we should hit 's' first
326− _ <- nodeRemoveChild currentParent $ Just x
323+ Just x <- getPreviousSibling e -- This can't be Nothing because we should hit 's' first
324+ _ <- removeChild currentParent $ Just x
327325 when (toNode s /= toNode x) go
328326 go
329− _ <- nodeRemoveChild currentParent $ Just e
327+ _ <- removeChild currentParent $ Just e
330328 return ()
331329
330+nodeClear :: IsNode self => self -> IO ()
331+nodeClear n = do
332+ mfc <- getFirstChild n
333+ case mfc of
334+ Nothing -> return ()
335+ Just fc -> do
336+ _ <- removeChild n $ Just fc
337+ nodeClear n
338+
332339--------------------------------------------------------------------------------
333340-- Adapters
334341--------------------------------------------------------------------------------
335342
336−wrapDomEvent :: (Functor (Event t), MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => e -> (e -> EventM event e () -> IO (IO ())) -> EventM event e a -> m (Event t a)
343+wrapDomEvent :: (Functor (Event t), MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => e -> (e -> EventM e event () -> IO (IO ())) -> EventM e event a -> m (Event t a)
337344wrapDomEvent element elementOnevent getValue = wrapDomEventMaybe element elementOnevent $ liftM Just getValue
338345
339−wrapDomEventMaybe :: (Functor (Event t), MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => e -> (e -> EventM event e () -> IO (IO ())) -> EventM event e (Maybe a) -> m (Event t a)
346+wrapDomEventMaybe :: (Functor (Event t), MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => e -> (e -> EventM e event () -> IO (IO ())) -> EventM e event (Maybe a) -> m (Event t a)
340347wrapDomEventMaybe element elementOnevent getValue = do
341348 postGui <- askPostGui
342349 runWithActions <- askRunWithActions
343350 e <- newEventWithTrigger $ \et -> do
344351 unsubscribe <- {-# SCC "a" #-} liftIO $ {-# SCC "b" #-} elementOnevent element $ {-# SCC "c" #-} do
345352 mv <- {-# SCC "d" #-} getValue
346− forM_ mv $ \v -> liftIO $ postGui $ runWithActions [et :=> v]
353+ forM_ mv $ \v -> liftIO $ postGui $ runWithActions [et :=> Identity v]
347354 return $ liftIO $ do
348355 {-# SCC "e" #-} unsubscribe
349356 return $! {-# SCC "f" #-} e
@@ -377,11 +384,11 @@ data EventTag
377384 | MouseoutTag
378385 | MouseoverTag
379386 | MouseupTag
380−-- | MousewheelTag -- webkitgtk only provides elementOnmousewheel (not elementOnwheel), but firefox does not support the mousewheel event; we should provide wheel (the equivalent, standard event), but we will need to make sure webkitgtk supports it first
387+ | MousewheelTag
381388 | ScrollTag
382389 | SelectTag
383390 | SubmitTag
384−-- | WheelTag -- See MousewheelTag
391+ | WheelTag
385392 | BeforecutTag
386393 | CutTag
387394 | BeforecopyTag
@@ -425,11 +432,11 @@ data EventName :: EventTag -> * where
425432 Mouseout :: EventName 'MouseoutTag
426433 Mouseover :: EventName 'MouseoverTag
427434 Mouseup :: EventName 'MouseupTag
428− --Mousewheel :: EventName 'MousewheelTag
435+ Mousewheel :: EventName 'MousewheelTag
429436 Scroll :: EventName 'ScrollTag
430437 Select :: EventName 'SelectTag
431438 Submit :: EventName 'SubmitTag
432− --Wheel :: EventName 'WheelTag
439+ Wheel :: EventName 'WheelTag
433440 Beforecut :: EventName 'BeforecutTag
434441 Cut :: EventName 'CutTag
435442 Beforecopy :: EventName 'BeforecopyTag
@@ -446,8 +453,8 @@ data EventName :: EventTag -> * where
446453
447454type family EventType en where
448455 EventType 'AbortTag = UIEvent
449− EventType 'BlurTag = UIEvent
450− EventType 'ChangeTag = UIEvent
456+ EventType 'BlurTag = FocusEvent
457+ EventType 'ChangeTag = DOM.Event
451458 EventType 'ClickTag = MouseEvent
452459 EventType 'ContextmenuTag = MouseEvent
453460 EventType 'DblclickTag = MouseEvent
@@ -459,87 +466,87 @@ type family EventType en where
459466 EventType 'DragstartTag = MouseEvent
460467 EventType 'DropTag = MouseEvent
461468 EventType 'ErrorTag = UIEvent
462− EventType 'FocusTag = UIEvent
463− EventType 'InputTag = UIEvent
464− EventType 'InvalidTag = UIEvent
465− EventType 'KeydownTag = UIEvent
466− EventType 'KeypressTag = UIEvent
467− EventType 'KeyupTag = UIEvent
469+ EventType 'FocusTag = FocusEvent
470+ EventType 'InputTag = DOM.Event
471+ EventType 'InvalidTag = DOM.Event
472+ EventType 'KeydownTag = KeyboardEvent
473+ EventType 'KeypressTag = KeyboardEvent
474+ EventType 'KeyupTag = KeyboardEvent
468475 EventType 'LoadTag = UIEvent
469476 EventType 'MousedownTag = MouseEvent
470− EventType 'MouseenterTag = UIEvent
471− EventType 'MouseleaveTag = UIEvent
477+ EventType 'MouseenterTag = MouseEvent
478+ EventType 'MouseleaveTag = MouseEvent
472479 EventType 'MousemoveTag = MouseEvent
473480 EventType 'MouseoutTag = MouseEvent
474481 EventType 'MouseoverTag = MouseEvent
475482 EventType 'MouseupTag = MouseEvent
476− --EventType 'MousewheelTag = MouseEvent
483+ EventType 'MousewheelTag = MouseEvent
477484 EventType 'ScrollTag = UIEvent
478485 EventType 'SelectTag = UIEvent
479− EventType 'SubmitTag = UIEvent
480− --EventType 'WheelTag = UIEvent
481− EventType 'BeforecutTag = UIEvent
482− EventType 'CutTag = UIEvent
483− EventType 'BeforecopyTag = UIEvent
484− EventType 'CopyTag = UIEvent
485− EventType 'BeforepasteTag = UIEvent
486− EventType 'PasteTag = UIEvent
487− EventType 'ResetTag = UIEvent
488− EventType 'SearchTag = UIEvent
489− EventType 'SelectstartTag = UIEvent
490− EventType 'TouchstartTag = UIEvent
491− EventType 'TouchmoveTag = UIEvent
492− EventType 'TouchendTag = UIEvent
493− EventType 'TouchcancelTag = UIEvent
494−
495−onEventName :: IsElement e => EventName en -> e -> EventM (EventType en) e () -> IO (IO ())
496−onEventName en = case en of
497− Abort -> elementOnabort
498− Blur -> elementOnblur
499− Change -> elementOnchange
500− Click -> elementOnclick
501− Contextmenu -> elementOncontextmenu
502− Dblclick -> elementOndblclick
503− Drag -> elementOndrag
504− Dragend -> elementOndragend
505− Dragenter -> elementOndragenter
506− Dragleave -> elementOndragleave
507− Dragover -> elementOndragover
508− Dragstart -> elementOndragstart
509− Drop -> elementOndrop
510− Error -> elementOnerror
511− Focus -> elementOnfocus
512− Input -> elementOninput
513− Invalid -> elementOninvalid
514− Keydown -> elementOnkeydown
515− Keypress -> elementOnkeypress
516− Keyup -> elementOnkeyup
517− Load -> elementOnload
518− Mousedown -> elementOnmousedown
519− Mouseenter -> elementOnmouseenter
520− Mouseleave -> elementOnmouseleave
521− Mousemove -> elementOnmousemove
522− Mouseout -> elementOnmouseout
523− Mouseover -> elementOnmouseover
524− Mouseup -> elementOnmouseup
525− --Mousewheel -> elementOnmousewheel
526− Scroll -> elementOnscroll
527− Select -> elementOnselect
528− Submit -> elementOnsubmit
529− --Wheel -> elementOnwheel
530− Beforecut -> elementOnbeforecut
531− Cut -> elementOncut
532− Beforecopy -> elementOnbeforecopy
533− Copy -> elementOncopy
534− Beforepaste -> elementOnbeforepaste
535− Paste -> elementOnpaste
536− Reset -> elementOnreset
537− Search -> elementOnsearch
538− Selectstart -> elementOnselectstart
539− Touchstart -> elementOntouchstart
540− Touchmove -> elementOntouchmove
541− Touchend -> elementOntouchend
542− Touchcancel -> elementOntouchcancel
486+ EventType 'SubmitTag = DOM.Event
487+ EventType 'WheelTag = WheelEvent
488+ EventType 'BeforecutTag = DOM.Event
489+ EventType 'CutTag = DOM.Event
490+ EventType 'BeforecopyTag = DOM.Event
491+ EventType 'CopyTag = DOM.Event
492+ EventType 'BeforepasteTag = DOM.Event
493+ EventType 'PasteTag = DOM.Event
494+ EventType 'ResetTag = DOM.Event
495+ EventType 'SearchTag = DOM.Event
496+ EventType 'SelectstartTag = DOM.Event
497+ EventType 'TouchstartTag = TouchEvent
498+ EventType 'TouchmoveTag = TouchEvent
499+ EventType 'TouchendTag = TouchEvent
500+ EventType 'TouchcancelTag = TouchEvent
501+
502+onEventName :: IsElement e => EventName en -> e -> EventM e (EventType en) () -> IO (IO ())
503+onEventName en e = case en of
504+ Abort -> on e E.abort
505+ Blur -> on e E.blurEvent
506+ Change -> on e E.change
507+ Click -> on e E.click
508+ Contextmenu -> on e E.contextMenu
509+ Dblclick -> on e E.dblClick
510+ Drag -> on e E.drag
511+ Dragend -> on e E.dragEnd
512+ Dragenter -> on e E.dragEnter
513+ Dragleave -> on e E.dragLeave
514+ Dragover -> on e E.dragOver
515+ Dragstart -> on e E.dragStart
516+ Drop -> on e E.drop
517+ Error -> on e E.error
518+ Focus -> on e E.focusEvent
519+ Input -> on e E.input
520+ Invalid -> on e E.invalid
521+ Keydown -> on e E.keyDown
522+ Keypress -> on e E.keyPress
523+ Keyup -> on e E.keyUp
524+ Load -> on e E.load
525+ Mousedown -> on e E.mouseDown
526+ Mouseenter -> on e E.mouseEnter
527+ Mouseleave -> on e E.mouseLeave
528+ Mousemove -> on e E.mouseMove
529+ Mouseout -> on e E.mouseOut
530+ Mouseover -> on e E.mouseOver
531+ Mouseup -> on e E.mouseUp
532+ Mousewheel -> on e E.mouseWheel
533+ Scroll -> on e E.scroll
534+ Select -> on e E.select
535+ Submit -> on e E.submit
536+ Wheel -> on e E.wheel
537+ Beforecut -> on e E.beforeCut
538+ Cut -> on e E.cut
539+ Beforecopy -> on e E.beforeCopy
540+ Copy -> on e E.copy
541+ Beforepaste -> on e E.beforePaste
542+ Paste -> on e E.paste
543+ Reset -> on e E.reset
544+ Search -> on e E.search
545+ Selectstart -> on e E.selectStart
546+ Touchstart -> on e E.touchStart
547+ Touchmove -> on e E.touchMove
548+ Touchend -> on e E.touchEnd
549+ Touchcancel -> on e E.touchCancel
543550
544551newtype EventResult en = EventResult { unEventResult :: EventResultType en }
545552
@@ -588,42 +595,43 @@ type family EventResultType (en :: EventTag) :: * where
588595 EventResultType 'TouchmoveTag = ()
589596 EventResultType 'TouchendTag = ()
590597 EventResultType 'TouchcancelTag = ()
598+ EventResultType 'MousewheelTag = ()
599+ EventResultType 'WheelTag = ()
591600
592−wrapDomEventsMaybe :: (Functor (Event t), IsElement e, MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => e -> (forall en. EventName en -> EventM (EventType en) e (Maybe (f en))) -> m (EventSelector t (WrapArg f EventName))
601+wrapDomEventsMaybe :: (Functor (Event t), IsElement e, MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => e -> (forall en. EventName en -> EventM e (EventType en) (Maybe (f en))) -> m (EventSelector t (WrapArg f EventName))
593602wrapDomEventsMaybe element handlers = do
594603 postGui <- askPostGui
595604 runWithActions <- askRunWithActions
596605 e <- newFanEventWithTrigger $ \(WrapArg en) et -> do
597− unsubscribe <- liftIO $ (onEventName en) element $ do
606+ unsubscribe <- onEventName en element $ do
598607 mv <- handlers en
599− forM_ mv $ \v -> liftIO $ postGui $ runWithActions [et :=> v]
608+ forM_ mv $ \v -> liftIO $ postGui $ runWithActions [et :=> Identity v]
600609 return $ liftIO $ do
601610 unsubscribe
602611 return $! e
603612
604−getKeyEvent :: EventM UIEvent e Int
613+getKeyEvent :: EventM e KeyboardEvent Int
605614getKeyEvent = do
606615 e <- event
607− liftIO $ do
608− which <- uiEventGetWhich e
609− if which /= 0 then return which else do
610− charCode <- uiEventGetCharCode e
611− if charCode /= 0 then return charCode else
612− uiEventGetKeyCode e
613−
614−getMouseEventCoords :: EventM MouseEvent e (Int, Int)
616+ which <- getWhich e
617+ if which /= 0 then return which else do
618+ charCode <- getCharCode e
619+ if charCode /= 0 then return charCode else
620+ getKeyCode e
621+
622+getMouseEventCoords :: EventM e MouseEvent (Int, Int)
615623getMouseEventCoords = do
616624 e <- event
617− liftIO $ bisequence (mouseEventGetClientX e, mouseEventGetClientY e)
625+ bisequence (getX e, getY e)
618626
619−defaultDomEventHandler :: IsElement e => e -> EventName en -> EventM (EventType en) e (Maybe (EventResult en))
627+defaultDomEventHandler :: IsElement e => e -> EventName en -> EventM e (EventType en) (Maybe (EventResult en))
620628defaultDomEventHandler e evt = liftM (Just . EventResult) $ case evt of
621629 Click -> return ()
622630 Dblclick -> return ()
623631 Keypress -> getKeyEvent
632+ Scroll -> getScrollTop e
624633 Keydown -> getKeyEvent
625634 Keyup -> getKeyEvent
626− Scroll -> liftIO $ elementGetScrollTop e
627635 Mousemove -> getMouseEventCoords
628636 Mouseup -> getMouseEventCoords
629637 Mousedown -> getMouseEventCoords
@@ -662,8 +670,10 @@ defaultDomEventHandler e evt = liftM (Just . EventResult) $ case evt of
662670 Touchmove -> return ()
663671 Touchend -> return ()
664672 Touchcancel -> return ()
673+ Mousewheel -> return ()
674+ Wheel -> return ()
665675
666−wrapElement :: forall t h m. (Functor (Event t), MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => (forall en. Element -> EventName en -> EventM (EventType en) Element (Maybe (EventResult en))) -> Element -> m (El t)
676+wrapElement :: forall t h m. (Functor (Event t), MonadIO m, MonadSample t m, MonadReflexCreateTrigger t m, Reflex t, HasPostGui t h m) => (forall en. Element -> EventName en -> EventM Element (EventType en) (Maybe (EventResult en))) -> Element -> m (El t)
667677wrapElement eh e = do
668678 es <- wrapDomEventsMaybe e $ eh e
669679 return $ El e es
@@ -748,17 +758,15 @@ simpleList xs mkChild = mapDyn (map snd . Map.toList) =<< flip list mkChild =<<
748758elDynHtml' :: MonadWidget t m => String -> Dynamic t String -> m (El t)
749759elDynHtml' elementTag html = do
750760 e <- buildEmptyElement elementTag (Map.empty :: Map String String)
751− let h = castToHTMLElement e
752− schedulePostBuild $ liftIO . htmlElementSetInnerHTML h =<< sample (current html)
753− addVoidAction $ fmap (liftIO . htmlElementSetInnerHTML h) $ updated html
761+ schedulePostBuild $ setInnerHTML e . Just =<< sample (current html)
762+ addVoidAction $ fmap (setInnerHTML e . Just) $ updated html
754763 wrapElement defaultDomEventHandler e
755764
756765elDynHtmlAttr' :: MonadWidget t m => String -> Map String String -> Dynamic t String -> m (El t)
757766elDynHtmlAttr' elementTag attrs html = do
758767 e <- buildEmptyElement elementTag attrs
759− let h = castToHTMLElement e
760− schedulePostBuild $ liftIO . htmlElementSetInnerHTML h =<< sample (current html)
761− addVoidAction $ fmap (liftIO . htmlElementSetInnerHTML h) $ updated html
768+ schedulePostBuild $ setInnerHTML e . Just =<< sample (current html)
769+ addVoidAction $ fmap (setInnerHTML e . Just) $ updated html
762770 wrapElement defaultDomEventHandler e
763771
764772data Link t
@@ -783,7 +791,7 @@ class HasDomEvent t a where
783791 domEvent :: EventName en -> a -> Event t (EventResultType en)
784792
785793instance Reflex t => HasDomEvent t (El t) where
786− domEvent en e = fmap unEventResult $ select (_el_events e) (WrapArg en)
794+ domEvent en e = fmap unEventResult $ Reflex.select (_el_events e) (WrapArg en)
787795
788796linkClass :: MonadWidget t m => String -> String -> m (Link t)
789797linkClass s c = do
@@ -795,7 +803,7 @@ link s = linkClass s ""
795803
796804button :: MonadWidget t m => String -> m (Event t ())
797805button s = do
798− (e, _) <- el' "button" $ text s
806+ (e, _) <- elAttr' "button" (Map.singleton "type" "button") $ text s
799807 return $ domEvent Click e
800808
801809newtype Workflow t m a = Workflow { unWorkflow :: m (a, Event t (Workflow t m a)) }
@@ -811,6 +819,9 @@ workflowView w0 = do
811819 eReplace <- liftM switch $ hold never $ fmap snd eResult
812820 return $ fmap fst eResult
813821
822+mapWorkflow :: (MonadWidget t m) => (a -> b) -> Workflow t m a -> Workflow t m b
823+mapWorkflow f (Workflow x) = Workflow (fmap (\(v,e) -> (f v, fmap (mapWorkflow f) e)) x)
824+
814825divClass :: forall t m a. MonadWidget t m => String -> m a -> m a
815826divClass = elClass "div"
816827
@@ -858,7 +869,7 @@ tabDisplay ulClass activeClass tabItems = do
858869 _ <- listWithKey dTabs (\k dTab -> do
859870 dAttrs <- mapDyn (\sel -> do
860871 let t1 = listToMaybe $ Map.keys tabItems
861− if sel == Just k || (sel == Nothing && t1 == Just k) then Map.empty else Map.singleton "style" "display:none;") dCurrentTab
872+ if sel == Just k || (sel == Nothing && t1 == Just k) then Map.empty else Map.singleton "style" "display:none;") dCurrentTab
862873 elDynAttr "div" dAttrs $ dyn =<< mapDyn snd dTab)
863874 return ()
864875 where
@@ -873,7 +884,7 @@ tabDisplay ulClass activeClass tabItems = do
873884unsafePlaceElement :: MonadWidget t m => Element -> m (El t)
874885unsafePlaceElement e = do
875886 p <- askParent
876− _ <- liftIO $ nodeAppendChild p $ Just e
887+ _ <- appendChild p $ Just e
877888 wrapElement defaultDomEventHandler e
878889
879890deriveGEq ''EventName