content: module Heist.Splices.Html where
  
  ------------------------------------------------------------------------------
  import           Data.Maybe
  import           Data.Text (Text)
  import qualified Text.XmlHtml as X
  
  ------------------------------------------------------------------------------
  import           Heist.Interpreted.Internal
  import           Heist.Internal.Types.HeistState
  
  
  ------------------------------------------------------------------------------
  -- | Name for the html splice.
  htmlTag :: Text
  htmlTag = "html"
  
  
  ------------------------------------------------------------------------------
  -- | The html splice runs all children and then traverses the returned node
  -- forest removing all head nodes.  Then it merges them all and prepends it to
  -- the html tag's child list.
  htmlImpl :: Monad n => Splice n
  htmlImpl = do
      node <- getParamNode
      children <- runNodeList $ X.childNodes node
      let (heads, mnode) = extractHeads $ node { X.elementChildren = children }
          new (X.Element t a c) = X.Element t a $
              X.Element "head" [] heads : c
          new n = n
      stopRecursion
      return [maybe node new mnode]
  
  ------------------------------------------------------------------------------
  -- | Extracts all heads from a node tree.
  extractHeads :: X.Node
               -- ^ The root (html) node
               -> ([X.Node], Maybe X.Node)
               -- ^ A tuple of a list of head nodes and the original tree with
               --   heads removed.
  extractHeads (X.Element t a c)
    | t == "head" = (c, Nothing)
    | otherwise   = (concat heads, Just $ X.Element t a (catMaybes mcs))
    where
      (heads, mcs) = unzip $ map extractHeads c
  extractHeads n = ([], Just n)
  
  