mangrove-0.1.0.0: src/Web/Mangrove/Parse/Tree/AfterHead.hs
{-|
Description: Token processing rules between the @\</head\>@ and @\<body\>@ tags.
Copyright: (c) 2020 Sam May
License: MPL-2.0
Maintainer: ag.eitilt@gmail.com
Stability: stable
Portability: portable
-}
module Web.Mangrove.Parse.Tree.AfterHead
( treeAfterHead
) where
import qualified Data.Text as T
import Web.Mangrove.Parse.Common.Error
import Web.Mangrove.Parse.Tokenize.Common
import Web.Mangrove.Parse.Tree.Common
import Web.Mangrove.Parse.Tree.InBody
import Web.Mangrove.Parse.Tree.InHead
import Web.Mangrove.Parse.Tree.Patch
import Web.Willow.Common.Parser
import Web.Willow.Common.Parser.Switch
-- | __HTML:__
-- @[the "after head" insertion mode]
-- (https://html.spec.whatwg.org/multipage/parsing.html#the-after-head-insertion-mode)@
--
-- The parsing instructions corresponding to the 'AfterHead' section of the
-- state machine.
treeAfterHead :: TreeBuilder TreeOutput
treeAfterHead = next >>= switch
[ If isWhitespace insertCharacter
, If isComment insertComment
, If isDoctype $ \t' ->
packTreeErrors [UnexpectedDoctype $ tokenDocumentType t'] t'
, If (isStartTag ["html"]) $ \t' -> do
push t'
treeInBody
, If (isStartTag ["body"]) $ \t' -> do
switchMode InBody
setFramesetNotOk
close <- closeCurrentNode_
insert <- insertElement t'
return $ close ++| insert
, If (isStartTag ["frameset"]) $ \t' -> do
switchMode InFrameset
close <- closeCurrentNode_
insert <- insertElement t'
return $ close ++| insert
, If (isStartTag
[ "base"
, "basefont"
, "bgsound"
, "link"
, "meta"
, "noframes"
, "script"
, "style"
, "template"
, "title"
]) $ \t' -> do
push t'
consTreeError UnexpectedMetadataOutsideOfHead <$> treeInHead
, If (isEndTag ["template"]) $ \t' -> do
push t'
treeInHead
, If (isEndTag ["body", "html", "br"]) anythingElse
, If (isStartTag ["head"]) $ \t' ->
packTreeErrors [DuplicateSingletonElement $ tokenElement t'] t'
, If isAnyEndTag $ \t' ->
packTreeErrors [UnmatchedEndTag $ tokenElement t'] t'
, Else anythingElse
]
where anythingElse t' = do
push t'
switchMode InBody
close <- closeCurrentNode_
insert <- insertElement_ $ emptyTagParams
{ tagName = T.pack "body"
}
packTree_ $ close ++ insert