packages feed

mangrove-0.1.0.0: src/Web/Mangrove/Parse/Tree/AfterBody.hs

{-|
Description:    Token processing rules between the closing @\</body\>@ and @\</html\>@ tags.

Copyright:      (c) 2020 Sam May
License:        MPL-2.0
Maintainer:     ag.eitilt@gmail.com

Stability:      stable
Portability:    portable
-}
module Web.Mangrove.Parse.Tree.AfterBody
    ( treeAfterBody
    ) where


import Web.Mangrove.Parse.Common.Error
import Web.Mangrove.Parse.Tree.Common
import Web.Mangrove.Parse.Tree.InBody
import Web.Mangrove.Parse.Tree.Patch
import Web.Willow.Common.Parser
import Web.Willow.Common.Parser.Switch


-- | __HTML:__
--      @[the "after body" insertion mode]
--      (https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-afterbody)@
-- 
-- The parsing instructions corresponding to the 'AfterBody' section of the
-- state machine.
treeAfterBody :: TreeBuilder TreeOutput
treeAfterBody = next >>= switch
    [ If isWhitespace $ \t' -> do
        push t'
        treeInBody
    , If isComment $ insertComment' InHtmlElement
        -- Even document fragments will always have an @\<html\>@ element as
        -- the root, so this 'InsertAt' will always target "the first element
        -- in the stack of open elements".
    , If isDoctype $ \t' ->
        packTreeErrors [UnexpectedDoctype $ tokenDocumentType t'] t'
    , If (isStartTag ["html"]) $ \t' -> do
        push t'
        treeInBody
    , If (isEndTag ["html"]) $ \t' -> do
        isFragment <- inFragment
        if isFragment
            then packTreeErrors [AbruptTemplateFragment] t'
            else switchMode AfterAfterBody *> packTreeErrors [] t'
    , If isEOF stopParsing
    , Else $ \t' -> do
        push t'
        switchMode InBody
        packTreeErrors_ [UnexpectedContentAfterBody]
    ]