@@ -5,6 +5,7 @@
55{-# LANGUAGE EmptyDataDecls #-}
66{-# LANGUAGE FlexibleContexts #-}
77{-# LANGUAGE FlexibleInstances #-}
8+{-# LANGUAGE GADTs #-}
89{-# LANGUAGE GeneralizedNewtypeDeriving #-}
910{-# LANGUAGE LambdaCase #-}
1011{-# LANGUAGE MultiParamTypeClasses #-}
@@ -24,6 +25,7 @@ import Reflex.Class as Reflex
2425import Reflex.Dom.Builder.Class
2526import Reflex.Dynamic
2627import Reflex.Host.Class
28+import qualified Reflex.Patch.DMap as PatchDMap
2729import qualified Reflex.Patch.DMapWithMove as PatchDMapWithMove
2830import Reflex.PerformEvent.Class
2931import Reflex.PostBuild.Class
@@ -45,10 +47,12 @@ import Data.Dependent.Sum
4547import Data.Functor.Compose
4648import Data.Functor.Constant
4749import Data.Functor.Misc
50+import Data.Functor.Product
4851import Data.IORef
4952import qualified Data.Map as Map
5053import Data.Maybe
51−import Data.Monoid
54+import Data.Monoid hiding (Product)
55+import Data.Some (Some)
5256import qualified Data.Some as Some
5357import Data.Text (Text)
5458import GHCJS.DOM.Document (Document, createDocumentFragment, createElement, createElementNS, createTextNode)
@@ -543,14 +547,23 @@ instance (Reflex t, MonadAdjust t m, MonadIO m, MonadHold t m, MonadFix m, Perfo
543547 return result
544548 return (result0, result')
545549 traverseDMapWithKeyWithAdjust = do
546− let updatedChildToUnreadiness :: forall x v'. Int -> ComposeMaybe (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v') x -> ComposeMaybe (Constant Int) x
547− updatedChildToUnreadiness cohortId = \case
548− ComposeMaybe Nothing -> ComposeMaybe Nothing -- The child is being deleted, so it's ready
549− ComposeMaybe (Just (Compose (_, _, alreadyReady, _)))
550− | alreadyReady -> ComposeMaybe Nothing -- The child is being added and is already ready
551− | otherwise -> ComposeMaybe $ Just $ Constant cohortId -- The child is being added and is not ready
552− childrenPatchToUnreadyPatch cohortId (PatchDMap m) = PatchDMap $ DMap.map (updatedChildToUnreadiness cohortId) m
553− hoistTraverseWithKeyWithAdjust traverseDMapWithKeyWithAdjust mapPatchDMap childrenPatchToUnreadyPatch $ \placeholders lastPlaceholderRef (PatchDMap p) -> do
550+ let updateChildUnreadiness (p :: PatchDMap k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) old = do
551+ let new :: forall a. k a -> ComposeMaybe (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') a -> IO (ComposeMaybe (Constant (IORef (ChildReadyState k))) a)
552+ new k (ComposeMaybe m) = ComposeMaybe <$> case m of
553+ Nothing -> return Nothing
554+ Just (Compose (_, _, sRef, _)) -> do
555+ readIORef sRef >>= \case
556+ ChildReadyState_Ready -> return Nothing -- Delete this child, since it's ready
557+ ChildReadyState_Unready _ -> do
558+ writeIORef sRef $ ChildReadyState_Unready $ Just $ Some.This k
559+ return $ Just $ Constant sRef
560+ delete _ (Constant sRef) = do
561+ writeIORef sRef $ ChildReadyState_Unready Nothing
562+ return $ Constant ()
563+ p' <- fmap PatchDMap $ DMap.traverseWithKey new $ unPatchDMap p
564+ _ <- DMap.traverseWithKey delete $ PatchDMap.getDeletions p old
565+ return $ applyAlways p' old
566+ hoistTraverseWithKeyWithAdjust traverseDMapWithKeyWithAdjust mapPatchDMap updateChildUnreadiness $ \placeholders lastPlaceholderRef (PatchDMap p) -> do
554567 phs <- readIORef placeholders
555568 forM_ (DMap.toList p) $ \(k :=> ComposeMaybe mv) -> do
556569 lastPlaceholder <- liftIO $ readIORef lastPlaceholderRef
@@ -559,19 +572,29 @@ instance (Reflex t, MonadAdjust t m, MonadIO m, MonadHold t m, MonadFix m, Perfo
559572 forM_ mv $ \(Compose (df, _, _, _)) -> df `insertBefore` nextPlaceholder
560573 writeIORef placeholders $! fromMaybe phs $ apply (weakenPatchDMapWith (\(Compose (_, ph, _, _)) -> ph) $ PatchDMap p) phs
561574 traverseDMapWithKeyWithAdjustWithMove = do
562− let updatedChildToUnreadiness :: forall x k v'. Int -> PatchDMapWithMove.NodeInfo k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v') x -> PatchDMapWithMove.NodeInfo k (Constant Int) x
563− updatedChildToUnreadiness cohortId = PatchDMapWithMove.nodeInfoMapFrom $ \case
564− PatchDMapWithMove.From_Insert (Compose (_, _, alreadyReady, _))
565− | alreadyReady -> PatchDMapWithMove.From_Delete -- The child is being added and is already ready
566− | otherwise -> PatchDMapWithMove.From_Insert $ Constant cohortId -- The child is being added and is not ready
567− PatchDMapWithMove.From_Delete -> PatchDMapWithMove.From_Delete -- The child is being deleted, so it's ready
568− PatchDMapWithMove.From_Move k -> PatchDMapWithMove.From_Move k -- The child is being moved, so its ready status should be moved
569− childrenPatchToUnreadyPatch cohortId = unsafePatchDMapWithMove . DMap.map (updatedChildToUnreadiness cohortId) . unPatchDMapWithMove
570− hoistTraverseWithKeyWithAdjust traverseDMapWithKeyWithAdjustWithMove mapPatchDMapWithMove childrenPatchToUnreadyPatch $ \placeholders lastPlaceholderRef (p_ :: PatchDMapWithMove k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v')) -> do
575+ let updateChildUnreadiness (p :: PatchDMapWithMove k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) old = do
576+ let new :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') a -> IO (PatchDMapWithMove.NodeInfo k (Constant (IORef (ChildReadyState k))) a)
577+ new k = PatchDMapWithMove.nodeInfoMapFromM $ \case
578+ PatchDMapWithMove.From_Insert (Compose (_, _, sRef, _)) -> do
579+ readIORef sRef >>= \case
580+ ChildReadyState_Ready -> return PatchDMapWithMove.From_Delete
581+ ChildReadyState_Unready _ -> do
582+ writeIORef sRef $ ChildReadyState_Unready $ Just $ Some.This k
583+ return $ PatchDMapWithMove.From_Insert $ Constant sRef
584+ PatchDMapWithMove.From_Delete -> return PatchDMapWithMove.From_Delete
585+ PatchDMapWithMove.From_Move fromKey -> return $ PatchDMapWithMove.From_Move fromKey
586+ deleteOrMove :: forall a. k a -> Product (Constant (IORef (ChildReadyState k))) (ComposeMaybe k) a -> IO (Constant () a)
587+ deleteOrMove _ (Pair (Constant sRef) (ComposeMaybe mToKey)) = do
588+ writeIORef sRef $ ChildReadyState_Unready $ Some.This <$> mToKey -- This will be Nothing if deleting, and Just if moving, so it works out in both cases
589+ return $ Constant ()
590+ p' <- fmap unsafePatchDMapWithMove $ DMap.traverseWithKey new $ unPatchDMapWithMove p
591+ _ <- DMap.traverseWithKey deleteOrMove $ PatchDMapWithMove.getDeletionsAndMoves p old
592+ return $ applyAlways p' old
593+ hoistTraverseWithKeyWithAdjust traverseDMapWithKeyWithAdjustWithMove mapPatchDMapWithMove updateChildUnreadiness $ \placeholders lastPlaceholderRef (p_ :: PatchDMapWithMove k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) -> do
571594 let p = unPatchDMapWithMove p_
572595 phsBefore <- readIORef placeholders
573596 lastPlaceholder <- liftIO $ readIORef lastPlaceholderRef
574− let collectIfMoved :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v') a -> IO (Constant (Maybe DOM.DocumentFragment) a)
597+ let collectIfMoved :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') a -> IO (Constant (Maybe DOM.DocumentFragment) a)
575598 collectIfMoved k e = do
576599 let mThisPlaceholder = Map.lookup (Some.This k) phsBefore -- Will be Nothing if this element wasn't present before
577600 nextPlaceholder = maybe lastPlaceholder snd $ Map.lookupGT (Some.This k) phsBefore
@@ -583,7 +606,7 @@ instance (Reflex t, MonadAdjust t m, MonadIO m, MonadHold t m, MonadFix m, Perfo
583606 Constant <$> mapM (`collectUpTo` nextPlaceholder) mThisPlaceholder
584607 collected <- DMap.traverseWithKey collectIfMoved p
585608 let !phsAfter = fromMaybe phsBefore $ apply (weakenPatchDMapWithMoveWith (\(Compose (_, ph, _, _)) -> ph) p_) phsBefore --TODO: Don't recompute this
586− let placeFragment :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v') a -> IO (Constant () a)
609+ let placeFragment :: forall a. k a -> PatchDMapWithMove.NodeInfo k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') a -> IO (Constant () a)
587610 placeFragment k e = do
588611 let nextPlaceholder = maybe lastPlaceholder snd $ Map.lookupGT (Some.This k) phsAfter
589612 case PatchDMapWithMove._nodeInfo_from e of
@@ -598,6 +621,11 @@ instance (Reflex t, MonadAdjust t m, MonadIO m, MonadHold t m, MonadFix m, Perfo
598621 mapM_ (\(k :=> v) -> void $ placeFragment k v) $ DMap.toDescList p -- We need to go in reverse order here, to make sure the placeholders are in the right spot at the right time
599622 writeIORef placeholders $! phsAfter
600623
624+data ChildReadyState k
625+ = ChildReadyState_Ready
626+ | ChildReadyState_Unready !(Maybe (Some k))
627+ deriving (Show, Read, Eq, Ord)
628+
601629hoistTraverseWithKeyWithAdjust :: forall (k :: * -> *) v v' t m p.
602630 ( PerformEvent t m
603631 , MonadAdjust t m
@@ -608,7 +636,7 @@ hoistTraverseWithKeyWithAdjust :: forall (k :: * -> *) v v' t m p.
608636 , MonadFix m
609637 , Patch (p k v)
610638 , PatchTarget (p k (Constant Int)) ~ DMap k (Constant Int)
611− , Monoid (p k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v'))
639+ , Monoid (p k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v'))
612640 , Patch (p k (Constant Int))
613641 )
614642 => (forall vv vv'.
@@ -618,16 +646,16 @@ hoistTraverseWithKeyWithAdjust :: forall (k :: * -> *) v v' t m p.
618646 -> m (DMap k vv', Event t (p k vv'))
619647 ) -- ^ The base monad's traversal
620648 -> (forall vv vv'. (forall a. vv a -> vv' a) -> p k vv -> p k vv') -- ^ A way of mapping over the patch type
621− -> (Int -> p k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v') -> p k (Constant Int)) -- ^ Given a patch for the children DOM elements, produce a patch for the childrens' unreadiness state
622− -> (IORef (Map.Map (Some.Some k) DOM.Text) -> IORef DOM.Text -> p k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v') -> IO ()) -- ^ Apply a patch to the DOM
649+ -> (p k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') -> DMap k (Constant (IORef (ChildReadyState k))) -> IO (DMap k (Constant (IORef (ChildReadyState k))))) -- ^ Given a patch for the children DOM elements, produce a patch for the childrens' unreadiness state
650+ -> (IORef (Map.Map (Some.Some k) DOM.Text) -> IORef DOM.Text -> p k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v') -> IO ()) -- ^ Apply a patch to the DOM
623651 -> (forall a. k a -> v a -> ImmediateDomBuilderT t m (v' a))
624652 -> DMap k v
625653 -> Event t (p k v)
626654 -> ImmediateDomBuilderT t m (DMap k v', Event t (p k v'))
627−hoistTraverseWithKeyWithAdjust base mapPatch childrenPatchToUnreadyPatch applyDomUpdate_ (f :: forall a. k a -> v a -> ImmediateDomBuilderT t m (v' a)) (dm0 :: DMap k v) dm' = do
655+hoistTraverseWithKeyWithAdjust base mapPatch updateChildUnreadiness applyDomUpdate_ (f :: forall a. k a -> v a -> ImmediateDomBuilderT t m (v' a)) (dm0 :: DMap k v) dm' = do
628656 initialEnv <- ImmediateDomBuilderT ask
629657 let parentUnreadyChildren = _immediateDomBuilderEnv_unreadyChildren initialEnv
630− pendingChange :: IORef (DMap k (Constant Int), p k (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v')) <- liftIO $ newIORef mempty
658+ pendingChange :: IORef (DMap k (Constant (IORef (ChildReadyState k))), p k (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v')) <- liftIO $ newIORef mempty
631659 haveEverBeenReady <- liftIO $ newIORef False
632660 placeholders <- liftIO $ newIORef $ error "placeholders not yet initialized"
633661 lastPlaceholderRef <- liftIO $ newIORef $ error "lastPlaceholderRef not yet initialized"
@@ -641,24 +669,30 @@ hoistTraverseWithKeyWithAdjust base mapPatch childrenPatchToUnreadyPatch applyDo
641669 let new = pred old
642670 writeIORef parentUnreadyChildren $! new
643671 when (new == 0) $ _immediateDomBuilderEnv_commitAction initialEnv
644− markChildReady :: forall a. Int -> k a -> IO ()
645− markChildReady markingCohortId k = do
646− (oldUnready, p) <- readIORef pendingChange
647− when (not (DMap.null oldUnready)) $ do
648− let clearUnreadiness = \case
649− Nothing -> Nothing
650− old@(Just (Constant pendingCohortId)) -> case pendingCohortId `compare` markingCohortId of
651− LT -> trace "Warning: marking a child as ready before it is in pendingChange" Nothing -- Should never happen; we're trying to mark something as done before it's been added to pendingChange
652− EQ -> Nothing -- We're marking the currently pending child as done
653− GT -> old -- We're marking a child as done that has already been superceded
654− newUnready = DMap.alter clearUnreadiness k oldUnready
655− writeIORef pendingChange $! (newUnready, p)
656− when (DMap.null newUnready) $ do
657− applyDomUpdate p
658− markSelfReady
659− dm'' <- zipListWithEvent (\cohortId -> mapPatch (\v -> Compose (cohortId, v))) [1 :: Int ..] dm'
660− (children0, children') <- lift $ base (\k (Compose (cohortId, v)) -> drawChildUpdate initialEnv (markChildReady cohortId k) $ f k v) (DMap.map (\v -> Compose (0, v)) dm0) dm''
661− let !initialUnready = DMap.mapMaybeWithKey (\_ (Compose (_, _, alreadyReady, _)) -> if alreadyReady then Nothing else Just $ Constant 0) children0
672+ markChildReady :: IORef (ChildReadyState k) -> IO ()
673+ markChildReady childReadyState = do
674+ readIORef childReadyState >>= \case
675+ ChildReadyState_Ready -> return ()
676+ ChildReadyState_Unready countedAt -> do
677+ writeIORef childReadyState ChildReadyState_Ready
678+ case countedAt of
679+ Nothing -> return ()
680+ Just (Some.This k) -> do -- This child has been counted as unready, so we need to remove it from the unready set
681+ (oldUnready, p) <- readIORef pendingChange
682+ when (not $ DMap.null oldUnready) $ do -- This shouldn't actually ever be null
683+ let newUnready = DMap.delete k oldUnready
684+ writeIORef pendingChange $! (newUnready, p)
685+ when (DMap.null newUnready) $ do
686+ applyDomUpdate p
687+ markSelfReady
688+ (children0, children') <- lift $ base (\k v -> drawChildUpdate initialEnv markChildReady $ f k v) dm0 dm'
689+ let processChild k (Compose (_, _, sRef, _)) = ComposeMaybe <$> do
690+ readIORef sRef >>= \case
691+ ChildReadyState_Ready -> return Nothing
692+ ChildReadyState_Unready _ -> do
693+ writeIORef sRef $ ChildReadyState_Unready $ Just $ Some.This k
694+ return $ Just $ Constant sRef
695+ initialUnready <- liftIO $ DMap.mapMaybeWithKey (\_ -> getComposeMaybe) <$> DMap.traverseWithKey processChild children0
662696 liftIO $ if DMap.null initialUnready
663697 then writeIORef haveEverBeenReady True
664698 else do
@@ -671,76 +705,34 @@ hoistTraverseWithKeyWithAdjust base mapPatch childrenPatchToUnreadyPatch applyDo
671705 _ <- DMap.traverseWithKey (\_ (Compose (df, _, _, _)) -> Constant () <$ append df) children0
672706 liftIO . writeIORef lastPlaceholderRef =<< textNodeInternal ("" :: Text)
673707 -- Note: the numbering here must match the numbering of dm''
674− children'' <- zipListWithEvent (,) [1 :: Int ..] children'
675− performEvent_ $ ffor children'' $ \(cohortId, p) -> liftIO $ do
708+ performEvent_ $ ffor children' $ \p -> liftIO $ do
676709 (oldUnready, oldP) <- readIORef pendingChange
677− let !newUnready = fromMaybe oldUnready $ apply (childrenPatchToUnreadyPatch cohortId p) oldUnready
678− !newP = p <> oldP
710+ newUnready <- updateChildUnreadiness p oldUnready
711+ let !newP = p <> oldP
679712 writeIORef pendingChange $! (newUnready, newP)
680713 when (DMap.null newUnready) $ do
681714 applyDomUpdate newP
682715 markSelfReady
683716 writeIORef pendingChange $! mempty
684717 return (result0, result')
685−{-
686− traverseDMapWithKeyWithAdjustWithMove (f :: forall a. k a -> v a -> ImmediateDomBuilderT t m (v' a)) (dm0 :: DMap k v) dm' = do
687− initialEnv <- ImmediateDomBuilderT ask
688− (children0, children') <- lift $ traverseDMapWithKeyWithAdjustWithMove (\k v -> drawChildUpdate initialEnv $ f k v) dm0 dm'
689− let result0 = DMap.map (\(Compose (_, _, v)) -> v) children0
690− placeholders0 = weakenDMapWith (\(Compose (_, ph, _)) -> ph) children0
691− result' = ffor children' $ mapPatchDMapWithMove $ \(Compose (_, _, r)) -> r
692− placeholders' = fforCheap children' $ weakenPatchDMapWithMoveWith $ \(Compose (_, ph, _)) -> ph
693− placeholders <- current . incrementalToDynamic <$> holdIncremental placeholders0 placeholders'
694− _ <- DMap.traverseWithKey (\_ (Compose (df, _, _)) -> Constant () <$ append df) children0
695− lastPlaceholder <- textNodeInternal ("" :: Text)
696− performEvent_ $ flip push children' $ \p_ -> do
697− let p = unPatchDMapWithMove p_
698− phsBefore <- sample placeholders
699− if DMap.null p then return Nothing else return $ Just $ do
700− let collectIfMoved :: forall a. k a -> DMapEdit k (Compose ((,,) DOM.DocumentFragment DOM.Text) v') a -> Performable m (Constant (Maybe DOM.DocumentFragment) a)
701− collectIfMoved k e = do
702− let mThisPlaceholder = Map.lookup (Some.This k) phsBefore -- Will be Nothing if this element wasn't present before
703− nextPlaceholder = maybe lastPlaceholder snd $ Map.lookupGT (Some.This k) phsBefore
704− case dmapEditMoved e of
705− False -> do
706− mapM_ (`deleteUpTo` nextPlaceholder) mThisPlaceholder
707− return $ Constant Nothing
708− True -> do
709− Constant <$> mapM (`collectUpTo` nextPlaceholder) mThisPlaceholder
710− collected <- DMap.traverseWithKey collectIfMoved p
711− let phsAfter = fromMaybe phsBefore $ apply (weakenPatchDMapWithMoveWith (\(Compose (_, ph, _)) -> ph) p_) phsBefore --TODO: Don't recompute this
712− let placeFragment :: forall a. k a -> DMapEdit k (Compose ((,,) DOM.DocumentFragment DOM.Text) v') a -> Performable m (Constant () a)
713− placeFragment k e = do
714− let nextPlaceholder = maybe lastPlaceholder snd $ Map.lookupGT (Some.This k) phsAfter
715− case e of
716− PatchDMapWithMove.From_Insert _ (Compose (df, _, _)) -> do
717− df `insertBefore` nextPlaceholder
718− PatchDMapWithMove.From_Delete _ -> do
719− return ()
720− PatchDMapWithMove.From_Move _ fromKey -> do
721− Just (Constant mdf) <- return $ DMap.lookup fromKey collected
722− mapM_ (`insertBefore` nextPlaceholder) mdf
723− return $ Constant ()
724− mapM_ (\(k :=> v) -> void $ placeFragment k v) $ DMap.toDescList p -- We need to go in reverse order here, to make sure the placeholders are in the right spot at the right time
725− return ()
726− return (result0, result')
727−-}
728718
729719drawChildUpdate :: MonadIO m
730720 => ImmediateDomBuilderEnv t
731− -> IO () -- This will NOT be called if the child is ready at initialization time; instead, a True will be returned for that item
721+ -> (IORef (ChildReadyState k) -> IO ()) -- This will NOT be called if the child is ready at initialization time; instead, the ChildReadyState return value will be ChildReadyState_Ready
732722 -> ImmediateDomBuilderT t m (v' a)
733− -> m (Compose ((,,,) DOM.DocumentFragment DOM.Text Bool) v' a)
723+ -> m (Compose ((,,,) DOM.DocumentFragment DOM.Text (IORef (ChildReadyState k))) v' a)
734724drawChildUpdate initialEnv markReady child = do
725+ childReadyState <- liftIO $ newIORef $ ChildReadyState_Unready Nothing
735726 unreadyChildren <- liftIO $ newIORef 0
736727 Just df <- createDocumentFragment $ _immediateDomBuilderEnv_document initialEnv
737728 (placeholder, result) <- runImmediateDomBuilderT ((,) <$> textNodeInternal ("" :: Text) <*> child) $ initialEnv
738729 { _immediateDomBuilderEnv_parent = toNode df
739730 , _immediateDomBuilderEnv_unreadyChildren = unreadyChildren
740− , _immediateDomBuilderEnv_commitAction = markReady
731+ , _immediateDomBuilderEnv_commitAction = markReady childReadyState
741732 }
742733 u <- liftIO $ readIORef unreadyChildren
743− return $ Compose (df, placeholder, u == 0, result)
734+ when (u == 0) $ liftIO $ writeIORef childReadyState ChildReadyState_Ready
735+ return $ Compose (df, placeholder, childReadyState, result)
744736
745737mkHasFocus :: (MonadHold t m, Reflex t) => Element er d t -> m (Dynamic t Bool)
746738mkHasFocus e = do