+ ins_mode_in_table_else = (t) ->
+ parse_error()
+ flag_foster_parenting = true # FIXME
+ ins_mode_in_body t
+ flag_foster_parenting = false
+ can_in_table = {
+ 'table': true
+ 'tbody': true
+ 'tfoot': true
+ 'thead': true
+ 'tr': true
+ }
+ clear_to_table_stopers = {
+ 'table': true
+ 'template': true
+ 'html': true
+ }
+ clear_stack_to_table_context = ->
+ loop
+ if clear_to_table_stopers[open_els[0].name]?
+ break
+ open_els.shift()
+ return
+ clear_to_table_body_stopers = {
+ 'tbody': true
+ 'tfoot': true
+ 'thead': true
+ 'template': true
+ 'html': true
+ }
+ clear_stack_to_table_body_context = ->
+ loop
+ if clear_to_table_body_stopers[open_els[0].name]?
+ break
+ open_els.shift()
+ return
+ clear_to_table_row_stopers = {
+ 'tr': true
+ 'template': true
+ 'html': true
+ }
+ clear_stack_to_table_row_context = ->
+ loop
+ if clear_to_table_row_stopers[open_els[0].name]?
+ break
+ open_els.shift()
+ return
+ clear_afe_to_marker = ->
+ loop
+ el = afe.shift()
+ if el.type is TYPE_AFE_MARKER
+ return
+ ins_mode_in_table = (t) ->
+ switch t.type
+ when TYPE_TEXT
+ if can_in_table[t.name]
+ original_insertion_mode = insertion_mode
+ insertion_mode = ins_mode_in_table_text
+ insertion_mode t
+ else
+ ins_mode_in_table_else t
+ when TYPE_COMMENT
+ tree_insert_a_comment t
+ when TYPE_DOCTYPE
+ parse_error()
+ when TYPE_START_TAG
+ switch t.name
+ when 'caption'
+ clear_stack_to_table_context()
+ afe.unshift new_afe_marker()
+ insert_html_element t
+ insertion_mode = ins_mode_in_caption
+ when 'colgroup'
+ clear_stack_to_table_context()
+ insert_html_element t
+ insertion_mode = ins_mode_in_column_group
+ when 'col'
+ clear_stack_to_table_context()
+ insert_html_element new_open_tag 'colgroup'
+ insertion_mode = ins_mode_in_column_group
+ insertion_mode t
+ when 'tbody', 'tfoot', 'thead'
+ clear_stack_to_table_context()
+ insert_html_element t
+ insertion_mode = ins_mode_in_table_body
+ when 'td', 'th', 'tr'
+ clear_stack_to_table_context()
+ insert_html_element new_open_tag 'tbody'
+ insertion_mode = ins_mode_in_table_body
+ insertion_mode t
+ when 'table'
+ parse_error()
+ if is_in_table_scope 'table'
+ loop
+ el = open_els.shift()
+ if el.name is 'table'
+ break
+ reset_insertion_mode()
+ insertion_mode t
+ when 'style', 'script', 'template'
+ ins_mode_in_head t
+ when 'input'
+ if token_is_input_hidden t
+ ins_mode_in_table_else t
+ else
+ parse_error()
+ insert_html_element t
+ open_els.shift()
+ # fixfull acknowledge sef-closing flag
+ when 'form'
+ parse_error()
+ if form_element_pointer?
+ return
+ if template_tag_is_open()
+ return
+ form_element_pointer = insert_html_element t
+ open_els.shift()
+ else
+ ins_mode_in_table_else t
+ when TYPE_END_TAG
+ switch t.name
+ when 'table'
+ if is_in_table_scope 'table'
+ loop
+ el = open_els.shift()
+ if el.name is 'table'
+ break
+ reset_insertion_mode()
+ else
+ parse_error
+ when 'body', 'caption', 'col', 'colgroup', 'html', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr'
+ parse_error()
+ when 'template'
+ ins_mode_in_head t
+ else
+ ins_mode_in_table_else t
+ when TYPE_EOF
+ ins_mode_in_body t
+ else
+ ins_mode_in_table_else t
+
+
+ ins_mode_in_table_text = (t) ->
+ switch t.type
+ when TYPE_TEXT
+ switch t.text
+ when "\u0000"
+ parse_error()
+ return
+ console.log "unimplemented ins_mode_in_table_text"
+ # FIXME CONTINUE
+
+ ins_mode_in_table_body = (t) ->
+ if t.type is TYPE_START_TAG and t.name is 'tr'
+ clear_stack_to_table_body_context()
+ insert_html_element t
+ return
+ if t.type is TYPE_START_TAG and (t.name is 'th' or t.name is 'td')
+ parse_error()
+ clear_stack_to_table_body_context()
+ insert_html_element new_open_tag 'tr'
+ insertion_mode = ins_mode_in_row
+ insertion_mode t
+ return
+ if t.type is TYPE_END_TAG and (t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead')
+ unless is_in_table_scope t.name # fixfull check namespace
+ parse_error()
+ return
+ clear_stack_to_table_body_context()
+ open_els.shift()
+ insertion_mode = ins_mode_in_table
+ return
+ if (t.type is TYPE_START_TAG and (t.name is 'caption' or t.name is 'col' or t.name is 'colgroup' or t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead')) or (t.type is TYPE_END_TAG and t.name is 'table')
+ has = false
+ for el in open_els
+ if el.name is 'tbody' or el.name is 'tfoot' or el.name is 'thead'
+ has = true
+ break
+ if table_scopers[el.name]
+ break
+ if !has
+ parse_error()
+ return
+ clear_stack_to_table_body_context()
+ open_els.shift()
+ insertion_mode = ins_mode_in_table
+ insertion_mode t
+ return
+ if t.type is TYPE_END_TAG and (t.name is 'body' or t.name is 'caption' or t.name is 'col' or t.name is 'colgroup' or t.name is 'html' or t.name is 'td' or t.name is 'th' or t.name is 'tr')
+ parse_error()
+ return
+ # Anything else
+ ins_mode_in_table t
+
+ ins_mode_in_row = (t) ->
+ if t.type is TYPE_START_TAG and (t.name is 'th' or t.name is 'td')
+ clear_stack_to_table_row_context()
+ insert_html_element t
+ insertion_mode = ins_mode_in_cell
+ afe.unshift new_afe_marker()
+ return
+ if t.type is TYPE_END_TAG and t.name is 'tr'
+ if is_in_table_scope 'tr'
+ clear_stack_to_table_row_context()
+ open_els.shift()
+ insertion_mode = ins_mode_in_table_body
+ else
+ parse_error()
+ return
+ if (t.type is TYPE_START_TAG and (t.name is 'caption' or t.name is 'col' or t.name is 'colgroup' or t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead' or t.name is 'tr')) or t.type is TYPE_END_TAG and t.name is 'table'
+ if is_in_table_scope 'tr'
+ clear_stack_to_table_row_context()
+ open_els.shift()
+ insertion_mode = ins_mode_in_table_body
+ insertion_mode t
+ else
+ parse_error()
+ return
+ if t.type is TYPE_END_TAG and (t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead')
+ if is_in_table_scope t.name # fixfull namespace
+ if is_in_table_scope 'tr'
+ clear_stack_to_table_row_context()
+ open_els.shift()
+ insertion_mode = ins_mode_in_table_body
+ insertion_mode t
+ else
+ parse_error()
+ return
+ if t.type is TYPE_END_TAG and (t.name is 'body' or t.name is 'caption' or t.name is 'col' or t.name is 'colgroup' or t.name is 'html' or t.name is 'td' or t.name is 'th')
+ parse_error()
+ return
+ # Anything else
+ ins_mode_in_table t
+
+ # http://www.w3.org/TR/html5/syntax.html#close-the-cell
+ close_the_cell = ->
+ generate_implied_end_tags()
+ unless open_els[0].name is 'td' or open_els[0] is 'th'
+ parse_error()
+ loop
+ el = open_els.shift()
+ if el.name is 'td' or el.name is 'th'
+ break
+ clear_afe_to_marker()
+ insertion_mode = ins_mode_in_row
+
+ # http://www.w3.org/TR/html5/syntax.html#parsing-main-intd
+ ins_mode_in_cell = (t) ->
+ if t.type is TYPE_END_TAG and (t.name is 'td' or t.name is 'th')
+ if is_in_table_scope t.name
+ generate_implied_end_tags()
+ if open_els[0].name isnt t.name
+ parse_error
+ loop
+ el = open_els.shift()
+ if el.name is t.name
+ break
+ clear_afe_to_marker()
+ insertion_mode = ins_mode_in_row
+ else
+ parse_error()
+ return
+ if t.type is TYPE_START_TAG and (t.name is 'caption' or t.name is 'col' or t.name is 'colgroup' or t.name is 'tbody' or t.name is 'td' or t.name is 'tfoot' or t.name is 'th' or t.name is 'thead' or t.name is 'tr')
+ has = false
+ for el in open_els
+ if el.name is 'td' or el.name is 'th'
+ has = true
+ break
+ if table_scopers[el.name]
+ break
+ if !has
+ parse_error()
+ return
+ close_the_cell()
+ insertion_mode t
+ return
+ if t.type is TYPE_END_TAG and (t.name is 'body' or t.name is 'caption' or t.name is 'col' or t.name is 'colgroup' or t.name is 'html')
+ parse_error()
+ return
+ if t.type is TYPE_END_TAG and (t.name is 'table' or t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead' or t.name is 'tr')
+ if is_in_table_scope t.name # fixfull namespace
+ close_the_cell()
+ insertion_mode t
+ else
+ parse_error()
+ return
+ # Anything Else
+ ins_mode_in_body t
+