JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
code cleanup and some minor fixes
authorJason Woofenden <jason@jasonwoof.com>
Tue, 22 Dec 2015 23:37:40 +0000 (18:37 -0500)
committerJason Woofenden <jason@jasonwoof.com>
Tue, 22 Dec 2015 23:37:40 +0000 (18:37 -0500)
parse-html.coffee

index cf84b32..01f2f32 100644 (file)
@@ -1260,18 +1260,18 @@ parse_html = (txt, parse_error_cb = null) ->
                        return
                if t.type is TYPE_START_TAG and t.name is 'noscript' and flag_scripting is false
                        insert_html_element t
-                       insertion_mode = ins_mode_in_head_noscript # FIXME implement
+                       insertion_mode = ins_mode_in_head_noscript
                        return
                if t.type is TYPE_START_TAG and t.name is 'script'
                        ail = adjusted_insertion_location()
                        el = token_to_element t, NS_HTML, ail
-                       el.flag 'parser-inserted', true # FIXME implement
+                       el.flag 'parser-inserted', true
                        # fixfull frament case
                        ail[0].children.splice ail[1], 0, el
                        open_els.unshift el
                        tok_state = tok_state_script_data
                        original_insertion_mode = insertion_mode # make sure orig... is defined
-                       insertion_mode = ins_mode_text # FIXME implement
+                       insertion_mode = ins_mode_text
                        return
                if t.type is TYPE_END_TAG and t.name is 'head'
                        open_els.shift() # will be a head element... spec says so
@@ -1285,7 +1285,7 @@ parse_html = (txt, parse_error_cb = null) ->
                        afe_push_marker()
                        flag_frameset_ok = false
                        insertion_mode = ins_mode_in_template
-                       template_insertion_modes.unshift ins_mode_in_template # FIXME implement
+                       template_insertion_modes.unshift ins_mode_in_template
                        return
                if t.type is TYPE_END_TAG and t.name is 'template'
                        if template_tag_is_open()
@@ -1308,9 +1308,36 @@ parse_html = (txt, parse_error_cb = null) ->
                ins_mode_in_head_else t
 
        # 8.2.5.4.5 http://www.w3.org/TR/html5/syntax.html#parsing-main-inheadnoscript
+       ins_mode_in_head_noscript_else = (t) ->
+               parse_error()
+               open_els.shift()
+               insertion_mode = ins_mode_in_head
+               insertion_mode t
        ins_mode_in_head_noscript = (t) ->
-               # FIXME ?fixfull
-               console.log "ins_mode_in_head_noscript unimplemented"
+               if t.type is TYPE_DOCTYPE
+                       parse_error()
+                       return
+               if t.type is TYPE_START_TAG
+                       ins_mode_in_body t
+                       return
+               if t.type is TYPE_END_TAG and t.name is 'noscript'
+                       open_els.shift()
+                       insertion_mode = ins_mode_in_head
+                       return
+               if (t.type is TYPE_TEXT and (t.text is "\t" or t.text is "\u000a" or t.text is "\u000c" or t.text is "\u000d" or t.text is ' ')) or t.type is TYPE_COMMENT or (t.type is TYPE_START_TAG and (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 'style'))
+                       ins_mode_in_head t
+                       return
+               if t.type is TYPE_END_TAG and t.name is 'br'
+                       ins_mode_in_head_noscript_else t
+                       return
+               if (t.type is TYPE_START_TAG and (t.name is 'head' or t.name is 'noscript')) or t.type is TYPE_END_TAG
+                       parse_error()
+                       return
+               # Anything else
+               ins_mode_in_head_noscript_else t
+               return
+
+
 
        # 8.2.5.4.6 http://www.w3.org/TR/html5/syntax.html#the-after-head-insertion-mode
        ins_mode_after_head_else = (t) ->
@@ -1365,149 +1392,168 @@ parse_html = (txt, parse_error_cb = null) ->
 
        # 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 node, i in open_els
-                       if node.name is name # FIXME check namespace too
+               for el, i in open_els
+                       if el.namespace is NS_HTML and el.name is name
                                generate_implied_end_tags name # arg is exception
                                parse_error() unless i is 0
                                while i >= 0
                                        open_els.shift()
                                        i -= 1
                                return
-                       if special_elements[node.name]? # FIXME check namespac too
+                       if special_elements[el.name] is el.namespace
                                parse_error()
                                return
+               return
        ins_mode_in_body = (t) ->
-               switch t.type
-                       when TYPE_TEXT
-                               switch t.text
-                                       when "\u0000"
-                                               parse_error()
-                                       when "\t", "\u000a", "\u000c", "\u000d", ' '
-                                               reconstruct_active_formatting_elements()
-                                               insert_character t
-                                       else
-                                               reconstruct_active_formatting_elements()
-                                               insert_character t
-                                               flag_frameset_ok = false
-                       when TYPE_COMMENT
-                               insert_comment t
-                       when TYPE_DOCTYPE
+               if t.type is TYPE_TEXT and t.text is "\u0000"
+                       parse_error()
+                       return
+               if is_space_tok t
+                       reconstruct_active_formatting_elements()
+                       insert_character t
+                       return
+               if t.type is TYPE_TEXT
+                       reconstruct_active_formatting_elements()
+                       insert_character t
+                       flag_frameset_ok = false
+                       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'
+                       parse_error()
+                       return if template_tag_is_open()
+                       root_attrs = open_els[open_els.length - 1].attrs
+                       for a of t.attrs_a
+                               root_attrs[a[0]] = a[1] unless root_attrs[a[0]]?
+                       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 'body'
+                       parse_error()
+                       return if open_els.length < 2
+                       second = open_els[open_els.length - 2]
+                       return unless second.ns is NS_HTML
+                       return unless second.name is 'body'
+                       return if template_tag_is_open()
+                       frameset_ok_flag = false
+                       for a of t.attrs_a
+                               second.attrs[a[0]] = a[1] unless second.attrs[a[0]]?
+                       return
+               if t.type is TYPE_START_TAG and t.name is 'frameset'
+                       parse_error()
+                       # FIXME CONTINUE
+                       return
+               # FIXME CONTINUE
+               if t.type is TYPE_START_TAG and (t.name is 'address' or t.name is 'article' or t.name is 'aside' or t.name is 'blockquote' or t.name is 'center' or t.name is 'details' or t.name is 'dialog' or t.name is 'dir' or t.name is 'div' or t.name is 'dl' or t.name is 'fieldset' or t.name is 'figcaption' or t.name is 'figure' or t.name is 'footer' or t.name is 'header' or t.name is 'hgroup' or t.name is 'main' or t.name is 'nav' or t.name is 'ol' or t.name is 'p' or t.name is 'section' or t.name is 'summary' or t.name is 'ul')
+                       close_p_if_in_button_scope()
+                       insert_html_element t
+                       return
+               if t.type is TYPE_START_TAG and (t.name is 'h1' or t.name is 'h2' or t.name is 'h3' or t.name is 'h4' or t.name is 'h5' or t.name is 'h6')
+                       close_p_if_in_button_scope()
+                       if open_els[0].name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
                                parse_error()
-                       when TYPE_START_TAG
-                               switch t.name
-                                       when 'html'
-                                               parse_error()
-                                               return if template_tag_is_open()
-                                               root_attrs = open_els[open_els.length - 1].attrs
-                                               for k, v of t.attrs
-                                                       root_attrs[k] = v unless root_attrs[k]?
-                                       when 'base', 'basefont', 'bgsound', 'link', 'meta', 'noframes', 'script', 'style', 'template', 'title'
-                                               # FIXME also do this for </template> (end tag)
-                                               return ins_mode_in_head t
-                                       when 'body'
-                                               parse_error()
-                                               # TODO
-                                       when 'frameset'
-                                               parse_error()
-                                               # TODO
-                                       when 'address', 'article', 'aside', 'blockquote', 'center', 'details', 'dialog', 'dir', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'header', 'hgroup', 'main', 'nav', 'ol', 'p', 'section', 'summary', 'ul'
-                                               close_p_if_in_button_scope()
-                                               insert_html_element t
-                                       when 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
-                                               close_p_if_in_button_scope()
-                                               if open_els[0].name in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
-                                                       parse_error()
-                                                       open_els.shift()
-                                               insert_html_element t
-                                       # TODO lots more to implement here
-                                       when 'a'
-                                               # If the list of active formatting elements
-                                               # contains an a element between the end of the list and
-                                               # the last marker on the list (or the start of the list
-                                               # if there is no marker on the list), then this is a
-                                               # parse error; run the adoption agency algorithm for
-                                               # the tag name "a", then remove that element from the
-                                               # list of active formatting elements and the stack of
-                                               # open elements if the adoption agency algorithm didn't
-                                               # already remove it (it might not have if the element
-                                               # is not in table scope).
-                                               found = false
-                                               for el in afe
-                                                       if el.type is TYPE_AFE_MARKER
-                                                               break
-                                                       if el.name is 'a'
-                                                               found = el
-                                               if found?
-                                                       parse_error()
-                                                       adoption_agency 'a'
-                                                       for el, i in afe
-                                                               if el is found
-                                                                       afe.splice i, 1
-                                                       for el, i in open_els
-                                                               if el is found
-                                                                       open_els.splice i, 1
-                                               reconstruct_active_formatting_elements()
-                                               el = insert_html_element t
-                                               afe_push el
-                                       when 'b', 'big', 'code', 'em', 'font', 'i', 's', 'small', 'strike', 'strong', 'tt', 'u'
-                                               reconstruct_active_formatting_elements()
-                                               el = insert_html_element t
-                                               afe_push el
-                                       when 'table'
-                                               # fixfull quirksmode thing
-                                               close_p_if_in_button_scope()
-                                               insert_html_element t
-                                               insertion_mode = ins_mode_in_table
-                                       # TODO lots more to implement here
-                                       else # any other start tag
-                                               reconstruct_active_formatting_elements()
-                                               insert_html_element t
-                       when TYPE_EOF
-                               ok_tags = {
-                                       dd: true, dt: true, li: true, p: true, tbody: true, td: true,
-                                       tfoot: true, th: true, thead: true, tr: true, body: true, html: true,
-                               }
-                               for t in open_els
-                                       unless ok_tags[t.name]?
-                                               parse_error()
-                                               break
-                               # TODO stack of template insertion modes thing
-                               stop_parsing()
-                       when TYPE_END_TAG
-                               switch t.name
-                                       when 'body'
-                                               unless is_in_scope 'body'
-                                                       parse_error()
-                                                       return
-                                               # TODO implement parse error and move to tree_after_body
-                                       when 'html'
-                                               unless is_in_scope 'body' # weird, but it's what the spec says
-                                                       parse_error()
-                                                       return
-                                               # TODO implement parse error and move to tree_after_body, reprocess
-                                       when 'address', 'article', 'aside', 'blockquote', 'button', 'center', 'details', 'dialog', 'dir', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'header', 'hgroup', 'listing', 'main', 'nav', 'ol', 'pre', 'section', 'summary', 'ul'
-                                               unless is_in_scope t.name, NS_HTML
-                                                       parse_error()
-                                                       return
-                                               generate_implied_end_tags()
-                                               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 and el.namespace is NS_HTML
-                                                               return
-                                       # TODO lots more close tags to implement here
-                                       when 'p'
-                                               unless is_in_button_scope 'p'
-                                                       parse_error()
-                                                       insert_html_element new_open_tag 'p'
-                                               close_p_element()
-                                       # TODO lots more close tags to implement here
-                                       when 'a', 'b', 'big', 'code', 'em', 'font', 'i', 'nobr', 's', 'small', 'strike', 'strong', 'tt', 'u'
-                                               adoption_agency t.name
-                                       # TODO lots more close tags to implement here
-                                       else
-                                               in_body_any_other_end_tag t.name
+                               open_els.shift()
+                       insert_html_element t
+                       return
+               # FIXME CONTINUE
+               if t.type is TYPE_START_TAG and t.name is 'a'
+                       # If the list of active formatting elements contains an a element
+                       # between the end of the list and the last marker on the list (or
+                       # the start of the list if there is no marker on the list), then
+                       # this is a parse error; run the adoption agency algorithm for the
+                       # tag name "a", then remove that element from the list of active
+                       # formatting elements and the stack of open elements if the
+                       # adoption agency algorithm didn't already remove it (it might not
+                       # have if the element is not in table scope).
+                       found = false
+                       for el in afe
+                               if el.type is TYPE_AFE_MARKER
+                                       break
+                               if el.name is 'a'
+                                       found = el
+                       if found?
+                               parse_error()
+                               adoption_agency 'a'
+                               for el, i in afe
+                                       if el is found
+                                               afe.splice i, 1
+                               for el, i in open_els
+                                       if el is found
+                                               open_els.splice i, 1
+                       reconstruct_active_formatting_elements()
+                       el = insert_html_element t
+                       afe_push el
+                       return
+               if t.type is TYPE_START_TAG and (t.name is 'b' or t.name is 'big' or t.name is 'code' or t.name is 'em' or t.name is 'font' or t.name is 'i' or t.name is 's' or t.name is 'small' or t.name is 'strike' or t.name is 'strong' or t.name is 'tt' or t.name is 'u')
+                       reconstruct_active_formatting_elements()
+                       el = insert_html_element t
+                       afe_push el
+                       return
+               if t.type is TYPE_START_TAG and t.name is 'table'
+                       # fixfull quirksmode thing
+                       close_p_if_in_button_scope()
+                       insert_html_element t
+                       insertion_mode = ins_mode_in_table
+                       return
+               # FIXME CONTINUE
+               if t.type is TYPE_EOF
+                       ok_tags = {
+                               dd: true, dt: true, li: true, p: true, tbody: true, td: true,
+                               tfoot: true, th: true, thead: true, tr: true, body: true, html: true,
+                       }
+                       for t in open_els
+                               unless ok_tags[t.name]?
+                                       parse_error()
+                                       break
+                       # FIXME stack of template insertion modes thing
+                       stop_parsing()
+                       return
+               # FIXME CONTINUE some of these next ones are out of order I think
+               if t.type is TYPE_END_TAG and t.name is 'body'
+                       unless is_in_scope 'body'
+                               parse_error()
+                               return
+                       # fixme implement parse error and move to tree_after_body
+                       return
+               if t.type is TYPE_END_TAG and t.name is 'html'
+                       unless is_in_scope 'body' # weird, but it's what the spec says
+                               parse_error()
+                               return
+                       # TODO implement parse error and move to tree_after_body, reprocess
+                       return
+               if t.type is TYPE_END_TAG and (t.name is 'address' or t.name is 'article' or t.name is 'aside' or t.name is 'blockquote' or t.name is 'button' or t.name is 'center' or t.name is 'details' or t.name is 'dialog' or t.name is 'dir' or t.name is 'div' or t.name is 'dl' or t.name is 'fieldset' or t.name is 'figcaption' or t.name is 'figure' or t.name is 'footer' or t.name is 'header' or t.name is 'hgroup' or t.name is 'listing' or t.name is 'main' or t.name is 'nav' or t.name is 'ol' or t.name is 'pre' or t.name is 'section' or t.name is 'summary' or t.name is 'ul')
+                       unless is_in_scope t.name, NS_HTML
+                               parse_error()
+                               return
+                       generate_implied_end_tags()
+                       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 and el.namespace is NS_HTML
+                                       return
+                       return
+               if t.type is TYPE_END_TAG and t.name is 'p'
+                       unless is_in_button_scope 'p'
+                               parse_error()
+                               insert_html_element new_open_tag 'p'
+                       close_p_element()
+                       return
+               if t.type is TYPE_END_TAG and (t.name is 'a' or t.name is 'b' or t.name is 'big' or t.name is 'code' or t.name is 'em' or t.name is 'font' or t.name is 'i' or t.name is 'nobr' or t.name is 's' or t.name is 'small' or t.name is 'strike' or t.name is 'strong' or t.name is 'tt' or t.name is 'u')
+                       adoption_agency t.name
+                       return
+               if t.type is TYPE_START_TAG # any other start tag
+                       reconstruct_active_formatting_elements()
+                       insert_html_element t
+                       return
+               if t.type is TYPE_END_TAG # any other end tag
+                       in_body_any_other_end_tag t.name
                return
 
        ins_mode_in_table_else = (t) ->