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 :: Text
htmlTag = Text
"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 :: forall (n :: * -> *). Monad n => Splice n
htmlImpl = do
    Node
node <- forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m Node
getParamNode
    Template
children <- forall (n :: * -> *). Monad n => Template -> Splice n
runNodeList forall a b. (a -> b) -> a -> b
$ Node -> Template
X.childNodes Node
node
    let (Template
heads, Maybe Node
mnode) = Node -> (Template, Maybe Node)
extractHeads forall a b. (a -> b) -> a -> b
$ Node
node { elementChildren :: Template
X.elementChildren = Template
children }
        new :: Node -> Node
new (X.Element Text
t [(Text, Text)]
a Template
c) = Text -> [(Text, Text)] -> Template -> Node
X.Element Text
t [(Text, Text)]
a forall a b. (a -> b) -> a -> b
$
            Text -> [(Text, Text)] -> Template -> Node
X.Element Text
"head" [] Template
heads forall a. a -> [a] -> [a]
: Template
c
        new Node
n = Node
n
    forall (m :: * -> *) (n :: * -> *). Monad m => HeistT n m ()
stopRecursion
    forall (m :: * -> *) a. Monad m => a -> m a
return [forall b a. b -> (a -> b) -> Maybe a -> b
maybe Node
node Node -> Node
new Maybe Node
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 :: Node -> (Template, Maybe Node)
extractHeads (X.Element Text
t [(Text, Text)]
a Template
c)
  | Text
t forall a. Eq a => a -> a -> Bool
== Text
"head" = (Template
c, forall a. Maybe a
Nothing)
  | Bool
otherwise   = (forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [Template]
heads, forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> Template -> Node
X.Element Text
t [(Text, Text)]
a (forall a. [Maybe a] -> [a]
catMaybes [Maybe Node]
mcs))
  where
    ([Template]
heads, [Maybe Node]
mcs) = forall a b. [(a, b)] -> ([a], [b])
unzip forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Node -> (Template, Maybe Node)
extractHeads Template
c
extractHeads Node
n = ([], forall a. a -> Maybe a
Just Node
n)