@@ -40,6 +40,7 @@ module Reflex.Dom.Builder.Hydration
4040 , DOM(..), runDOMForest
4141 , hydrateDOM
4242 , hydrateNode
43+ , getPreviousNode, setPreviousNode
4344 , runHydrationDomBuilderT
4445 , askParent
4546 , askEvents
@@ -47,6 +48,8 @@ module Reflex.Dom.Builder.Hydration
4748 , textNodeInternal
4849 , deleteBetweenExclusive
4950 , extractBetweenExclusive
51+ , deleteBetweenInclusive
52+ , extractBetweenInclusive
5053 , deleteUpTo
5154 , extractUpTo
5255 , SupportsHydrationDomBuilder
@@ -482,6 +485,21 @@ extractBetweenExclusive df s e = liftJSM $ do
482485 f <- eval ("(function(df,s,e) { var x; for(;;) { x = s['nextSibling']; if(e===x) { break; }; df['appendChild'](x); } })" :: Text)
483486 void $ call f f (df, s, e)
484487
488+-- | s and e must both be children of the same node and s must precede e;
489+-- all nodes between s and e will be removed, including s and e
490+deleteBetweenInclusive :: (MonadJSM m, IsNode start, IsNode end) => start -> end -> m ()
491+deleteBetweenInclusive s e = do
492+ df <- createDocumentFragment =<< getOwnerDocumentUnchecked s
493+ extractBetweenInclusive df s e -- In many places in HydrationDomBuilderT, we assume that things always have a parent; by adding them to this DocumentFragment, we maintain that invariant
494+
495+-- | s and e must both be children of the same node and s must precede e; all
496+-- nodes between s and e will be moved into the given DocumentFragment,
497+-- including s and e
498+extractBetweenInclusive :: (MonadJSM m, IsNode start, IsNode end) => DOM.DocumentFragment -> start -> end -> m ()
499+extractBetweenInclusive df s e = liftJSM $ do
500+ f <- eval ("(function(df,s,e) { var x = s; var next; for(;;) { next = x['nextSibling']; df['appendChild'](x); if(e===x) { break; }; x = next; } })" :: Text)
501+ void $ call f f (df, s, e)
502+
485503-- | s and e must both be children of the same node and s must precede e;
486504-- s and all nodes between s and e will be removed, but e will not be removed
487505{-# INLINABLE deleteUpTo #-}