@@ -38,6 +38,8 @@ module Reflex.Dom.Builder.Hydration
3838 , HydrationRunnerT (..)
3939 , runHydrationRunnerT
4040 , DOM(..), runDOMForest
41+ , hydrateDOM
42+ , hydrateNode
4143 , runHydrationDomBuilderT
4244 , askParent
4345 , askEvents
@@ -399,6 +401,10 @@ getPreviousNode = HydrationRunnerT get
399401setPreviousNode :: Monad m => Maybe DOM.Node -> HydrationRunnerT t m ()
400402setPreviousNode = HydrationRunnerT . put
401403
404+{-# INLINABLE getPrerenderDepth #-}
405+getPrerenderDepth :: MonadIO m => HydrationDomBuilderT t m Word
406+getPrerenderDepth = liftIO . readIORef =<< HydrationDomBuilderT (asks _hydrationDomBuilderEnv_prerenderDepth)
407+
402408{-# INLINABLE getParent #-}
403409getParent :: MonadIO m => HydrationDomBuilderT t m DOM.Node
404410getParent = liftIO . readIORef =<< HydrationDomBuilderT (asks _hydrationDomBuilderEnv_parent)
@@ -437,8 +443,8 @@ makeNodeInternal mkNode = do
437443-- @check@. The previous node reference is also updated.
438444hydrateNode
439445 :: (MonadJSM m, IsNode node, Typeable node)
440− => (node -> HydrationRunnerT t m Bool) -> HydrationRunnerT t m node -> (DOM.JSVal -> node) -> HydrationRunnerT t m node
441−hydrateNode check mkNode constructor = do
446+ => (node -> HydrationRunnerT t m Bool) -> (DOM.JSVal -> node) -> HydrationRunnerT t m node
447+hydrateNode check constructor = do
442448 parent <- askParent
443449 liftIO $ putStr $ show (typeRep constructor) <> ": "
444450 lastHydrationNode <- getPreviousNode
@@ -587,7 +593,6 @@ makeElement elementTag cfg child = do
587593 writeChan events [EventTriggerRef ref :=> TriggerInvocation v (return ())])
588594 getHydrationMode >>= \case
589595 HydrationMode_Immediate -> do
590− -- TODO: prerender needs completely replacing
591596 e <- makeNodeInternal buildElement
592597 p <- liftIO $ newIORef $ toNode e
593598 -- Run the child builder with updated parent and previous sibling references
@@ -603,8 +608,15 @@ makeElement elementTag cfg child = do
603608 let env' = env { _hydrationDomBuilderEnv_parent = parent}
604609 (result, childDom) <- HydrationDomBuilderT $ lift $ lift $ runStateT (runReaderT (unHydrationDomBuilderT child) env') []
605610 wrapResult <- liftIO newEmptyMVar
611+ prerenderDepth <- getPrerenderDepth
606612 let activateElement = do
607− e <- hydrateNode hasSSRAttribute buildElement DOM.Element
613+ e <- case prerenderDepth of
614+ 0 -> hydrateNode hasSSRAttribute DOM.Element
615+ _ -> do
616+ e <- buildElement
617+ maybe (askParent >>= \p -> Node.appendChild_ p e) (insertAfter e) =<< getPreviousNode
618+ setPreviousNode $ Just $ toNode e
619+ pure e
608620 -- Update the parent node used by the children
609621 liftIO $ writeIORef parent $ toNode e
610622 -- Setup events, store the result so we can wait on it later
@@ -644,12 +656,16 @@ textNodeInternal !t mSetContents = getHydrationMode >>= \case
644656 pure n
645657 HydrationMode_Hydrating -> do
646658 doc <- askDocument
659+ prerenderDepth <- getPrerenderDepth
647660 let activateText = do
648661 liftIO $ putStrLn $ "Action: Text: " <> show (DOM.toJSString t)
649− n <- hydrateNode (const $ pure True) (createTextNode doc t) DOM.Text
650− --case mSetContents of
651− -- Nothing -> liftIO $ putStrLn "No update events for text"
652− -- Just e -> requestDomAction_ $ setNodeValue n . Just <$> e
662+ n <- case prerenderDepth of
663+ 0 -> hydrateNode (const $ pure True) DOM.Text
664+ _ -> do
665+ tn <- createTextNode doc t
666+ maybe (askParent >>= \p -> Node.appendChild_ p tn) (insertAfter tn) =<< getPreviousNode
667+ setPreviousNode $ Just $ toNode tn
668+ pure tn
653669 mapM_ (requestDomAction_ . fmap (setNodeValue n . Just)) mSetContents
654670 hydrateDOM $ DOM_Node activateText
655671 pure $ error "textNodeInternal: DOM.Text"
@@ -663,9 +679,16 @@ commentNodeInternal !t mSetContents = getHydrationMode >>= \case
663679 pure n
664680 HydrationMode_Hydrating -> do
665681 doc <- askDocument
682+ prerenderDepth <- getPrerenderDepth
666683 let activateComment = do
667684 liftIO $ putStrLn $ "Action: Comment: " <> show (DOM.toJSString t)
668− n <- hydrateNode (const $ pure True) (createComment doc t) DOM.Comment
685+ n <- case prerenderDepth of
686+ 0 -> hydrateNode (const $ pure True) DOM.Comment
687+ _ -> do
688+ tn <- createComment doc t
689+ maybe (askParent >>= \p -> Node.appendChild_ p tn) (insertAfter tn) =<< getPreviousNode
690+ setPreviousNode $ Just $ toNode tn
691+ pure tn
669692 mapM_ (requestDomAction_ . fmap (setNodeValue n . Just)) mSetContents
670693 hydrateDOM $ DOM_Node activateComment
671694 pure $ error "commentNodeInternal: DOM.Comment"