From 60dfaaf9f047176c2c7a7eca7aa4b263537007d1 Mon Sep 17 00:00:00 2001 From: Jason Woofenden Date: Wed, 23 Dec 2015 17:52:35 -0500 Subject: [PATCH] namespace checking cleanup --- parse-html.coffee | 200 +++++++++++++++++++++++++---------------------------- 1 file changed, 95 insertions(+), 105 deletions(-) diff --git a/parse-html.coffee b/parse-html.coffee index 8b30cf7..60a10f3 100644 --- a/parse-html.coffee +++ b/parse-html.coffee @@ -326,12 +326,13 @@ mathml_text_integration = { is_mathml_text_integration_point = (el) -> return mathml_text_integration[el.name] is el.namespace is_html_integration = (el) -> # DON'T PASS A TOKEN - if el.namespace is NS_MATHML and el.name is 'annotation-xml' - if el.attrs.encoding? - if el.attrs.encoding.toLowerCase() is 'text/html' - return true - if el.attrs.encoding.toLowerCase() is 'application/xhtml+xml' - return true + if el.namespace is NS_MATHML + if el.name is 'annotation-xml' + if el.attrs.encoding? + if el.attrs.encoding.toLowerCase() is 'text/html' + return true + if el.attrs.encoding.toLowerCase() is 'application/xhtml+xml' + return true return false if el.namespace is NS_SVG if el.name is 'foreignObject' or el.name is 'desc' or el.name is 'title' @@ -342,28 +343,25 @@ h_tags = { h1:NS_HTML, h2:NS_HTML, h3:NS_HTML, h4:NS_HTML, h5:NS_HTML, h6:NS_HTML } -# FIXME namespacify foster_parenting_targets = { - table: true - tbody: true - tfoot: true - thead: true - tr: true + table: NS_HTML + tbody: NS_HTML + tfoot: NS_HTML + thead: NS_HTML + tr: NS_HTML } -# FIXME namespacify -# all html I presume end_tag_implied = { - dd: true - dt: true - li: true - option: true - optgroup: true - p: true - rb: true - rp: true - rt: true - rtc: true + dd: NS_HTML + dt: NS_HTML + li: NS_HTML + option: NS_HTML + optgroup: NS_HTML + p: NS_HTML + rb: NS_HTML + rp: NS_HTML + rt: NS_HTML + rtc: NS_HTML } el_is_special = (e) -> @@ -566,7 +564,7 @@ parse_html = (args) -> # But first... the helpers template_tag_is_open = -> for t in open_els - if t.name is 'template' # maybe should also check: and t.namespace is 'html' + if t.name is 'template' and t.namespace is NS_HTML return true return false is_in_scope_x = (tag_name, scope, namespace) -> @@ -615,11 +613,12 @@ parse_html = (args) -> return false return false # this checks for a particular element, not by name - el_is_in_scope = (el) -> - for t in open_els - if t is el + # this requires a namespace match + el_is_in_scope = (needle) -> + for el in open_els + if el is needle return true - if standard_scopers[t.name] is t.namespace + if standard_scopers[el.name] is el.namespace return false return false @@ -635,15 +634,15 @@ parse_html = (args) -> open_els.shift() return clear_to_table_body_stopers = { - 'tbody': true - 'tfoot': true - 'thead': true - 'template': true - 'html': true + tbody: NS_HTML + tfoot: NS_HTML + thead: NS_HTML + template: NS_HTML + html: NS_HTML } clear_stack_to_table_body_context = -> loop - if clear_to_table_body_stopers[open_els[0].name]? + if clear_to_table_body_stopers[open_els[0].name] is open_els[0].namespace break open_els.shift() return @@ -833,7 +832,7 @@ parse_html = (args) -> debug_log "tree: #{serialize_els doc.children, false, true}" debug_log "open_els: #{serialize_els open_els, true, true}" debug_log "afe: #{serialize_els afe, true, true}" - if open_els[0].name is subject + if open_els[0].name is subject and open_els[0].namespace is NS_HTML el = open_els[0] open_els.shift() # remove it from the list of active formatting elements (if found) @@ -1117,14 +1116,14 @@ parse_html = (args) -> # http://www.w3.org/TR/html5/syntax.html#close-a-p-element close_p_element = -> generate_implied_end_tags 'p' # arg is exception - if open_els[0].name isnt 'p' + unless open_els[0].name is 'p' and open_els[0].namespace is NS_HTML parse_error() while open_els.length > 1 # just in case el = open_els.shift() - if el.name is 'p' + if el.name is 'p' and el.namespace is NS_HTML return close_p_if_in_button_scope = -> - if is_in_button_scope 'p' + if is_in_button_scope 'p', NS_HTML close_p_element() # http://www.w3.org/TR/html5/syntax.html#insert-a-character @@ -1185,7 +1184,7 @@ parse_html = (args) -> # If foster parenting is enabled and target is a table, tbody, tfoot, # thead, or tr element Foster parenting happens when content is # misnested in tables. - if flag_foster_parenting and foster_parenting_targets[target.name] + if flag_foster_parenting and foster_parenting_targets[target.name] is target.namespace loop # once. this is here so we can ``break`` to "abort these substeps" # 1. Let last template be the last template element in the # stack of open elements, if any. @@ -1318,7 +1317,7 @@ parse_html = (args) -> # 8.2.5.3 http://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags # http://www.w3.org/TR/html5/syntax.html#generate-implied-end-tags generate_implied_end_tags = (except = null) -> - while end_tag_implied[open_els[0].name] and open_els[0].name isnt except + while end_tag_implied[open_els[0].name] is open_els[0].namespace and open_els[0].name isnt except open_els.shift() # 8.2.5.4 The rules for parsing tokens in HTML content @@ -1480,7 +1479,7 @@ parse_html = (args) -> parse_error() loop el = open_els.shift() - if el.name is 'template' + if el.name is 'template' and el.namespace is NS_HTML break clear_afe_to_marker() template_ins_modes.shift() @@ -1579,7 +1578,7 @@ parse_html = (args) -> # 8.2.5.4.7 http://www.w3.org/TR/html5/syntax.html#parsing-main-inbody in_body_any_other_end_tag = (name) -> # factored out because adoption agency calls it for el, i in open_els - if el.namespace is NS_HTML and el.name is name + if el.name is name and el.namespace is NS_HTML generate_implied_end_tags name # arg is exception parse_error() unless i is 0 while i >= 0 @@ -1667,7 +1666,7 @@ parse_html = (args) -> stop_parsing() return if t.type is TYPE_END_TAG and t.name is 'body' - unless is_in_scope 'body' + unless is_in_scope 'body', NS_HTML parse_error() return ok_tags = { @@ -1684,7 +1683,7 @@ parse_html = (args) -> ins_mode = ins_mode_after_body return if t.type is TYPE_END_TAG and t.name is 'html' - unless is_in_scope 'body' + unless is_in_scope 'body', NS_HTML parse_error() return ok_tags = { @@ -1707,7 +1706,7 @@ parse_html = (args) -> return if t.type is TYPE_START_TAG and h_tags[t.name]? close_p_if_in_button_scope() - if h_tags[open_els[0]] is NS_HTML + if h_tags[open_els[0].name] is open_els[0].namespace parse_error() open_els.shift() insert_html_element t @@ -2110,7 +2109,7 @@ parse_html = (args) -> return if t.type is TYPE_EOF parse_error() - if open_els[0].name is 'script' + if open_els[0].name is 'script' and open_els[0].namespace is NS_HTML open_els[0].flag 'already started', true open_els.shift() ins_mode = original_ins_mode @@ -2138,17 +2137,10 @@ parse_html = (args) -> ins_mode_in_body t flag_foster_parenting = false return - can_in_table = { # FIXME do this inline like everywhere else - 'table': true - 'tbody': true - 'tfoot': true - 'thead': true - 'tr': true - } ins_mode_in_table = (t) -> switch t.type when TYPE_TEXT - if can_in_table[t.name] + if t.name is 'table' or t.name is 'tbody' or t.name is 'tfoot' or t.name is 'thead' or t.name is 'tr' original_ins_mode = ins_mode ins_mode = ins_mode_in_table_text process_token t @@ -2185,10 +2177,10 @@ parse_html = (args) -> process_token t when 'table' parse_error() - if is_in_table_scope 'table' + if is_in_table_scope 'table', NS_HTML loop el = open_els.shift() - if el.name is 'table' + if el.name is 'table' and el.namespace is NS_HTML break reset_ins_mode() process_token t @@ -2215,14 +2207,14 @@ parse_html = (args) -> when TYPE_END_TAG switch t.name when 'table' - if is_in_table_scope 'table' + if is_in_table_scope 'table', NS_HTML loop el = open_els.shift() - if el.name is 'table' + if el.name is 'table' and el.namespace is NS_HTML break reset_ins_mode() else - parse_error + parse_error() when 'body', 'caption', 'col', 'colgroup', 'html', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr' parse_error() when 'template' @@ -2263,13 +2255,13 @@ parse_html = (args) -> # 8.2.5.4.11 http://www.w3.org/TR/html5/syntax.html#parsing-main-incaption ins_mode_in_caption = (t) -> if t.type is TYPE_END_TAG and t.name is 'caption' - if is_in_table_scope 'caption' + if is_in_table_scope 'caption', NS_HTML generate_implied_end_tags() if open_els[0].name isnt 'caption' parse_error() loop el = open_els.shift() - if el.name is 'caption' + if el.name is 'caption' and el.namespace is NS_HTML break clear_afe_to_marker() ins_mode = ins_mode_in_table @@ -2279,10 +2271,10 @@ parse_html = (args) -> 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')) or t.type is TYPE_END_TAG and t.name is 'table' parse_error() - if is_in_table_scope 'caption' + if is_in_table_scope 'caption', NS_HTML loop el = open_els.shift() - if el.name is 'caption' + if el.name is 'caption' and el.namespace is NS_HTML break clear_afe_to_marker() ins_mode = ins_mode_in_table @@ -2315,7 +2307,7 @@ parse_html = (args) -> t.acknowledge_self_closing() return if t.type is TYPE_END_TAG and t.name is 'colgroup' - if open_els[0].name is 'colgroup' + if open_els[0].name is 'colgroup' and open_els.namespace is NS_HTML open_els.shift() ins_mode = ins_mode_in_table else @@ -2354,7 +2346,7 @@ parse_html = (args) -> process_token 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 + unless is_in_table_scope t.name, NS_HTML parse_error() return clear_stack_to_table_body_context() @@ -2364,10 +2356,10 @@ parse_html = (args) -> 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' + if el.namespace is NS_HTML and (el.name is 'tbody' or el.name is 'tfoot' or el.name is 'thead') has = true break - if table_scopers[el.name] + if table_scopers[el.name] is el.namespace break if !has parse_error() @@ -2392,7 +2384,7 @@ parse_html = (args) -> afe_push_marker() return if t.type is TYPE_END_TAG and t.name is 'tr' - if is_in_table_scope 'tr' + if is_in_table_scope 'tr', NS_HTML clear_stack_to_table_row_context() open_els.shift() ins_mode = ins_mode_in_table_body @@ -2400,7 +2392,7 @@ parse_html = (args) -> 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' + if is_in_table_scope 'tr', NS_HTML clear_stack_to_table_row_context() open_els.shift() ins_mode = ins_mode_in_table_body @@ -2409,8 +2401,8 @@ parse_html = (args) -> 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' + if is_in_table_scope t.name, NS_HTML + if is_in_table_scope 'tr', NS_HTML clear_stack_to_table_row_context() open_els.shift() ins_mode = ins_mode_in_table_body @@ -2427,11 +2419,11 @@ parse_html = (args) -> # 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' + unless (open_els[0].name is 'td' or open_els[0] is 'th') and open_els[0].namespace is NS_HTML parse_error() loop el = open_els.shift() - if el.name is 'td' or el.name is 'th' + if el.namespace is NS_HTML and (el.name is 'td' or el.name is 'th') break clear_afe_to_marker() ins_mode = ins_mode_in_row @@ -2439,13 +2431,13 @@ parse_html = (args) -> # 8.2.5.4.15 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 + if is_in_table_scope t.name, NS_HTML generate_implied_end_tags() - if open_els[0].name isnt t.name - parse_error + unless (open_els[0].name is t.name) and open_els[0].namespace is NS_HTML + parse_error() loop el = open_els.shift() - if el.name is t.name + if el.name is t.name and el.namespace is NS_HTML break clear_afe_to_marker() ins_mode = ins_mode_in_row @@ -2455,10 +2447,10 @@ parse_html = (args) -> 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' + if el.namespace is NS_HTML and (el.name is 'td' or el.name is 'th') has = true break - if table_scopers[el.name] + if table_scopers[el.name] is el.namespace break if !has parse_error() @@ -2470,7 +2462,7 @@ parse_html = (args) -> 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 + if is_in_table_scope t.name, NS_HTML close_the_cell() process_token t else @@ -2497,36 +2489,37 @@ parse_html = (args) -> 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' + if open_els[0].name is 'option' and open_els[0].namespace is NS_HTML 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' + if open_els[0].name is 'option' and open_els[0].namespace is NS_HTML open_els.shift() - if open_els[0].name is 'optgroup' + if open_els[0].name is 'optgroup' and open_els[0].namespace is NS_HTML 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' + if open_els[0].name is 'option' and open_els[0].namespace in NS_HTML + if open_els[1].name is 'optgroup' and open_els[0].namespace is NS_HTML + open_els.shift() + if open_els[0].name is 'optgroup' and open_els[0].namespace is NS_HTML 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' + if open_els[0].name is 'option' and open_els[0].namespace is NS_HTML 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' + if is_in_select_scope 'select', NS_HTML loop el = open_els.shift() - if el.name is 'select' + if el.name is 'select' and el.namespace is NS_HTML break reset_ins_mode() else @@ -2536,7 +2529,7 @@ parse_html = (args) -> parse_error() loop el = open_els.shift() - if el.name is 'select' + if el.name is 'select' and el.namespace is NS_HTML break reset_ins_mode() # spec says that this is the same as but it doesn't say @@ -2544,11 +2537,11 @@ parse_html = (args) -> 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' + if is_in_select_scope 'select', NS_HTML return loop el = open_els.shift() - if el.name is 'select' + if el.name is 'select' and el.namespace is NS_HTML break reset_ins_mode() process_token t @@ -2569,7 +2562,7 @@ parse_html = (args) -> parse_error() loop el = open_els.shift() - if el.name is 'select' + if el.name is 'select' and el.namespace is NS_HTML break reset_ins_mode() process_token t @@ -2580,7 +2573,7 @@ parse_html = (args) -> return loop el = open_els.shift() - if el.name is 'select' + if el.name is 'select' and el.namespace is NS_HTML break reset_ins_mode() process_token t @@ -2637,7 +2630,7 @@ parse_html = (args) -> parse_error() loop el = open_els.shift() - if el.name is 'template' # fixfull check namespace + if el.name is 'template' and el.namespace is NS_HTML break clear_afe_to_marker() template_ins_modes.shift() @@ -2688,7 +2681,6 @@ parse_html = (args) -> 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 @@ -2705,7 +2697,6 @@ parse_html = (args) -> 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() @@ -3984,12 +3975,12 @@ parse_html = (args) -> return if c is '"' parse_error() - tok_cur_tag.public_identifier = '' # FIXME should this go in @attrs or @text? + tok_cur_tag.public_identifier = '' tok_state = tok_state_doctype_public_identifier_double_quoted return if c is "'" parse_error() - tok_cur_tag.public_identifier = '' # FIXME should this go in @attrs or @text? + tok_cur_tag.public_identifier = '' tok_state = tok_state_doctype_public_identifier_single_quoted return if c is '>' @@ -4016,12 +4007,12 @@ parse_html = (args) -> return if c is '"' parse_error() - tok_cur_tag.public_identifier = '' # FIXME should this go in @attrs or @text? + tok_cur_tag.public_identifier = '' tok_state = tok_state_doctype_public_identifier_double_quoted return if c is "'" parse_error() - tok_cur_tag.public_identifier = '' # FIXME should this go in @attrs or @text? + tok_cur_tag.public_identifier = '' tok_state = tok_state_doctype_public_identifier_single_quoted return if c is '>' @@ -4414,8 +4405,8 @@ parse_html = (args) -> # tokenizer initialization tok_state = tok_state_data - if args.name is "one_that_breaks #1" - throw "hi" # console.log "hi" + if args.name is "namespace-sensitivity.dat #1" + console.log "hi" # proccess input # http://www.w3.org/TR/html5/syntax.html#tree-construction while flag_parsing @@ -4434,7 +4425,6 @@ serialize_els = (els, shallow, show_ids) -> serialized += t.serialize shallow, show_ids return serialized -# TODO export TYPE_* module.exports.parse_html = parse_html module.exports.debug_log_reset = debug_log_reset module.exports.debug_log_each = debug_log_each -- 1.7.10.4