+ # 8.2.5.4.16 http://www.w3.org/TR/html5/syntax.html#parsing-main-inselect
+ ins_mode_in_select = (t) ->
+ if t.type is TYPE_TEXT and t.text is "\u0000"
+ parse_error()
+ return
+ if t.type is TYPE_TEXT
+ insert_character t
+ return
+ if t.type is TYPE_COMMENT
+ insert_comment t
+ return
+ if t.type is TYPE_DOCTYPE
+ parse_error()
+ return
+ if t.type is TYPE_START_TAG and t.name is 'html'
+ ins_mode_in_body t
+ return
+ if t.type is TYPE_START_TAG and t.name is 'option'
+ if open_els[0].name is 'option'
+ open_els.shift()
+ insert_html_element t
+ return
+ if t.type is TYPE_START_TAG and t.name is 'optgroup'
+ if open_els[0].name is 'option'
+ open_els.shift()
+ if open_els[0].name is 'optgroup'
+ open_els.shift()
+ insert_html_element t
+ return
+ if t.type is TYPE_END_TAG and t.name is 'optgroup'
+ if open_els[0].name is 'option' and open_els[1].name is 'optgroup'
+ open_els.shift()
+ if open_els[0].name is 'optgroup'
+ open_els.shift()
+ else
+ parse_error()
+ return
+ if t.type is TYPE_END_TAG and t.name is 'option'
+ if open_els[0].name is 'option'
+ open_els.shift()
+ else
+ parse_error()
+ return
+ if t.type is TYPE_END_TAG and t.name is 'select'
+ if is_in_select_scope 'select'
+ loop
+ el = open_els.shift()
+ if el.name is 'select'
+ break
+ reset_insertion_mode()
+ else
+ parse_error()
+ return
+ if t.type is TYPE_START_TAG and t.name is 'select'
+ parse_error()
+ loop
+ el = open_els.shift()
+ if el.name is 'select'
+ break
+ reset_insertion_mode()
+ # spec says that this is the same as </select> but it doesn't say
+ # to check scope first
+ return
+ if t.type is TYPE_START_TAG and (t.name is 'input' or t.name is 'keygen' or t.name is 'textarea')
+ parse_error()
+ if is_in_select_scope 'select'
+ return
+ loop
+ el = open_els.shift()
+ if el.name is 'select'
+ break
+ reset_insertion_mode()
+ insertion_mode t
+ return
+ if t.type is TYPE_START_TAG and (t.name is 'script' or t.name is 'template')
+ ins_mode_in_head t
+ return
+ if t.type is TYPE_EOF
+ ins_mode_in_body t
+ return
+ # Anything else
+ parse_error()
+ return
+
+ # 8.2.5.4.17 http://www.w3.org/TR/html5/syntax.html#parsing-main-inselectintable
+ ins_mode_in_select_in_table = (t) ->
+ if t.type is TYPE_START_TAG and (t.name is 'caption' or t.name is 'table' or t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead' or t.name is 'tr' or t.name is 'td' or t.name is 'th')
+ parse_error()
+ loop
+ el = open_els.shift()
+ if el.name is 'select'
+ break
+ reset_insertion_mode()
+ insertion_mode t
+ return
+ if t.type is TYPE_END_TAG and (t.name is 'caption' or t.name is 'table' or t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead' or t.name is 'tr' or t.name is 'td' or t.name is 'th')
+ parse_error()
+ unless is_in_table_scope t.name, NS_HTML
+ return
+ loop
+ el = open_els.shift()
+ if el.name is 'select'
+ break
+ reset_insertion_mode()
+ insertion_mode t
+ return
+ # Anything else
+ ins_mode_in_select t
+ return
+
+ # 8.2.5.4.18 http://www.w3.org/TR/html5/syntax.html#parsing-main-intemplate
+ ins_mode_in_template = (t) ->
+ if t.type is TYPE_TEXT or t.type is TYPE_COMMENT or t.type is TYPE_DOCTYPE
+ ins_mode_in_body t
+ return
+ if (t.type is TYPE_START_TAG and (t.name is 'base' or t.name is 'basefont' or t.name is 'bgsound' or t.name is 'link' or t.name is 'meta' or t.name is 'noframes' or t.name is 'script' or t.name is 'style' or t.name is 'template' or t.name is 'title')) or (t.type is TYPE_END_TAG and t.name is 'template')
+ ins_mode_in_head t
+ return
+ if t.type is TYPE_START_TAG and (t.name is 'caption' or t.name is 'colgroup' or t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead')
+ template_insertion_modes.shift()
+ template_insertion_modes.unshift ins_mode_in_table
+ insertion_mode = ins_mode_in_table
+ insertion_mode t
+ return
+ if t.type is TYPE_START_TAG and t.name is 'col'
+ template_insertion_modes.shift()
+ template_insertion_modes.unshift ins_mode_in_column_group
+ insertion_mode = ins_mode_in_column_group
+ insertion_mode t
+ return
+ if t.type is TYPE_START_TAG and t.name is 'tr'
+ template_insertion_modes.shift()
+ template_insertion_modes.unshift ins_mode_in_table_body
+ insertion_mode = ins_mode_in_table_body
+ insertion_mode t
+ return
+ if t.type is TYPE_START_TAG and (t.name is 'td' or t.name is 'th')
+ template_insertion_modes.shift()
+ template_insertion_modes.unshift ins_mode_in_row
+ insertion_mode = ins_mode_in_row
+ insertion_mode t
+ return
+ if t.type is TYPE_START_TAG
+ template_insertion_modes.shift()
+ template_insertion_modes.unshift ins_mode_in_body
+ insertion_mode = ins_mode_in_body
+ insertion_mode t
+ return
+ if t.type is TYPE_END_TAG
+ parse_error()
+ return
+ if t.type is EOF
+ unless template_tag_is_open()
+ stop_parsing()
+ return
+ parse_error()
+ loop
+ el = open_els.shift()
+ if el.name is 'template' # fixfull check namespace
+ break
+ clear_afe_to_marker()
+ template_insertion_modes.shift()
+ reset_insertion_mode()
+ insertion_mode t
+
+ # 8.2.5.4.19 http://www.w3.org/TR/html5/syntax.html#parsing-main-afterbody
+ ins_mode_after_body = (t) ->
+ if is_space_tok t
+ ins_mode_in_body t
+ return
+ if t.type is TYPE_COMMENT
+ insert_comment t, [open_els[0], open_els[0].children.length]
+ return
+ if t.type is TYPE_DOCTYPE
+ parse_error()
+ return
+ if t.type is TYPE_START_TAG and t.name is 'html'
+ ins_mode_in_body t
+ return
+ if t.type is TYPE_END_TAG and t.name is 'html'
+ # fixfull fragment case
+ insertion_mode = ins_mode_after_after_body
+ return
+ if t.type is TYPE_EOF
+ stop_parsing()
+ return
+ # Anything ELse
+ parse_error()
+ insertion_mode = ins_mode_in_body
+ insertion_mode t
+
+ # 8.2.5.4.20 http://www.w3.org/TR/html5/syntax.html#parsing-main-inframeset
+ ins_mode_in_frameset = (t) ->
+ if is_space_tok t
+ insert_character t
+ return
+ if t.type is TYPE_COMMENT
+ insert_comment t
+ return
+ if t.type is TYPE_DOCTYPE
+ parse_error()
+ return
+ if t.type is TYPE_START_TAG and t.name is 'html'
+ ins_mode_in_body t
+ return
+ if t.type is TYPE_START_TAG and t.name is 'frameset'
+ insert_html_element t
+ return
+ if t.type is TYPE_END_TAG and t.name is 'frameset'
+ # TODO ?correct for: "if the current node is the root html element"
+ if open_els.length is 1
+ parse_error()
+ return # fragment case
+ open_els.shift()
+ if flag_fragment_parsing is false and open_els[0].name isnt 'frameset'
+ insertion_mode = ins_mode_after_frameset
+ return
+ if t.type is TYPE_START_TAG and t.name is 'frame'
+ insert_html_element t
+ open_els.shift()
+ t.acknowledge_self_closing()
+ return
+ if t.type is TYPE_START TAG and t.name is 'noframes'
+ ins_mode_in_head t
+ return
+ if t.type is TYPE_EOF
+ # TODO ?correct for: "if the current node is not the root html element"
+ if open_els.length isnt 1
+ parse_error()
+ stop_parsing()
+ return
+ # Anything else
+ parse_error()
+ return
+
+ # 8.2.5.4.21 http://www.w3.org/TR/html5/syntax.html#parsing-main-afterframeset
+ ins_mode_after_frameset = (t) ->
+ if is_space_tok t
+ insert_character t
+ return
+ if t.type is TYPE_COMMENT
+ insert_comment t
+ return
+ if t.type is TYPE_DOCTYPE
+ parse_error()
+ return
+ if t.type is TYPE_START_TAG and t.name is 'html'
+ ins_mode_in_body t
+ return
+ if t.type is TYPE_END_TAG and t.name is 'html'
+ insert_mode = ins_mode_after_after_frameset
+ return
+ if t.type is TYPE_START_TAG and t.name is 'noframes'
+ ins_mode_in_head t
+ return
+ if t.type is TYPE_EOF
+ stop_parsing()
+ return
+ # Anything else
+ parse_error()
+ return
+
+ # 8.2.5.4.22 http://www.w3.org/TR/html5/syntax.html#the-after-after-body-insertion-mode
+ ins_mode_after_after_body = (t) ->
+ if t.type is TYPE_COMMENT
+ insert_comment t, [doc, doc.children.length]
+ return
+ if t.type is TYPE_DOCTYPE or is_space_tok(t) or (t.type is TYPE_START_TAG and t.name is 'html')
+ ins_mode_in_body t
+ return
+ if t.type is TYPE_EOF
+ stop_parsing()
+ return
+ # Anything else
+ parse_error()
+ insertion_mode = ins_mode_in_body
+ return
+
+ # 8.2.5.4.23 http://www.w3.org/TR/html5/syntax.html#the-after-after-frameset-insertion-mode
+ ins_mode_after_after_frameset = (t) ->
+ if t.type is TYPE_COMMENT
+ insert_comment t, [doc, doc.children.length]
+ return
+ if t.type is TYPE_DOCTYPE or is_space_tok(t) or (t.type is TYPE_START_TAG and t.name is 'html')
+ ins_mode_in_body t
+ return
+ if t.type is TYPE_EOF
+ stop_parsing()
+ return
+ if t.type is TYPE_START_TAG and t.name is 'noframes'
+ ins_mode_in_head t
+ return
+ # Anything else
+ parse_error()
+ return
+
+
+
+
+