 M: in-select-mode tree-insert* drop unimplemented* ;
 M: in-select-in-table-mode tree-insert* drop unimplemented* ;
 M: in-template-mode tree-insert* drop unimplemented* ;
-M: after-body-mode tree-insert* drop unimplemented* ;
+M: after-body-mode tree-insert*
+    drop {
+        { [ dup "\t\n\f\r\s" member? ] [ over tree>> push ] }
+        { [ dup comment? ] [ over tree>> push ] }
+        { [ dup doctype? ] [ drop ] }
+        { [ dup { [ tag? ] [ name>> "html" = ] } 1&& ] [
+            unimplemented*
+         ] }
+        { [ dup { [ end-tag? ] [ name>> "html" = ] } 1&& ] [
+            ! XXX: make this a function
+            "html" pick tree>> find-matching-tag
+            unclip
+                swap >>children
+                swap >>end-tag
+            over tree>> push
+
+            after-after-body-mode >>insertion-mode
+        ] }
+        [
+            unimplemented*
+        ]
+    } cond ;
 M: in-frameset-mode tree-insert* drop unimplemented* ;
 M: after-frameset-mode tree-insert* drop unimplemented* ;
-M: after-after-body-mode tree-insert* drop unimplemented* ;
+
+M: after-after-body-mode tree-insert*
+    drop {
+        { [ dup comment? ] [ over tree>> push ] }
+        { [ dup doctype? ] [ unimplemented*  ] }
+        { [ dup "\t\n\f\r\s" member? ] [ unimplemented*  ] }
+        { [ dup { [ tag? ] [ name>> "html" = ] } 1&& ] [ unimplemented* ] }
+        ! eof
+        { [ dup f = ] [ drop ] }
+        [
+            ! XXX: parse error
+            [ in-body-mode >>insertion-mode ] dip tree-insert
+        ]
+    } cond ;
+
 M: after-after-frameset-mode tree-insert* drop unimplemented* ;
 
 : tree-insert ( document obj -- document )
-    over tree-insertion-mode>> tree-insert* ;
+    over insertion-mode>> tree-insert* ;
 
 MEMO: load-entities ( -- assoc )
     "vocab:html5/entities.json" utf8 file-contents json> ;

        stack name unmatched-closing-tag-error
    ] if* ;

GENERIC: tree-insert* ( document obj tree-insertion-mode -- document )

M: initial-mode tree-insert*
    drop {
        ! XXX: don't just drop this?
        { [ dup CHAR: \t = ] [ drop ] }
        { [ dup CHAR: \n = ] [ drop ] }
        { [ dup CHAR: \f = ] [ drop ] }
        { [ dup CHAR: \r = ] [ drop ] }
        { [ dup CHAR: \s = ] [ drop ] }
        { [ dup tag? ] [ over tree>> push ] }
        { [ dup end-tag? ] [
            dup name>> pick tree>> find-matching-tag


TUPLE: document
quirks-mode?
limited-quirks-mode?
iframe-srcdoc?
scripting? ! set in constructor
frameset-ok? ! frameset-ok? but we want default to f
fostering-parent?
tree
tree-doctype
head-element-pointer ! set during insertion time
parser-cannot-change-mode-flag
insertion-mode
original-insertion-mode
last
node
