X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=parse-html.coffee;h=5dc05a9eb271b2fabcd671e3bb09ddfbb77d2239;hb=d94782242ab0addd8ba355c0eccab9c97418c320;hp=06c2a1b04e67c55ad0fbf7e5e1b2b78396efa99f;hpb=3ff49c30096e8e97599b98755157f9a692937f58;p=peach-html5-editor.git diff --git a/parse-html.coffee b/parse-html.coffee index 06c2a1b..5dc05a9 100644 --- a/parse-html.coffee +++ b/parse-html.coffee @@ -16,13 +16,17 @@ # This file implements a parser for html snippets, meant to be used by a -# WYSIWYG editor. Hence it does not attempt to parse doctypes, , -# or tags, nor does it produce the top level "document" node in the dom -# tree, nor nodes for html, head or body. Comments containing "fixfull" -# indicate places where additional code is needed for full HTML document -# parsing. +# WYSIWYG editor. + +# The implementation is a pretty direct implementation of the parsing algorithm +# described here: +# http://www.w3.org/TR/html5/syntax.html#preprocessing-the-input-stream +# +# Deviations from that spec: +# +# Purposeful: search this file for "WTAG" # -# Instead, the data structure produced by this parser is an array of Nodes. +# Not finished yet: search this file for "fixfull", "TODO" and "FIXME" # stacks/lists @@ -336,14 +340,17 @@ special_elements = { h2:NS_HTML, h3:NS_HTML, h4:NS_HTML, h5:NS_HTML, h6:NS_HTML, head:NS_HTML, header:NS_HTML, hgroup:NS_HTML, hr:NS_HTML, html:NS_HTML, iframe:NS_HTML, img:NS_HTML, input:NS_HTML, isindex:NS_HTML, li:NS_HTML, link:NS_HTML, - listing:NS_HTML, main:NS_HTML, marquee:NS_HTML, meta:NS_HTML, nav:NS_HTML, - noembed:NS_HTML, noframes:NS_HTML, noscript:NS_HTML, object:NS_HTML, - ol:NS_HTML, p:NS_HTML, param:NS_HTML, plaintext:NS_HTML, pre:NS_HTML, - script:NS_HTML, section:NS_HTML, select:NS_HTML, source:NS_HTML, - style:NS_HTML, summary:NS_HTML, table:NS_HTML, tbody:NS_HTML, td:NS_HTML, - template:NS_HTML, textarea:NS_HTML, tfoot:NS_HTML, th:NS_HTML, - thead:NS_HTML, title:NS_HTML, tr:NS_HTML, track:NS_HTML, ul:NS_HTML, - wbr:NS_HTML, xmp:NS_HTML, + listing:NS_HTML, main:NS_HTML, marquee:NS_HTML, + + menu:NS_HTML,menuitem:NS_HTML, # WATWG adds these + + meta:NS_HTML, nav:NS_HTML, noembed:NS_HTML, noframes:NS_HTML, + noscript:NS_HTML, object:NS_HTML, ol:NS_HTML, p:NS_HTML, param:NS_HTML, + plaintext:NS_HTML, pre:NS_HTML, script:NS_HTML, section:NS_HTML, + select:NS_HTML, source:NS_HTML, style:NS_HTML, summary:NS_HTML, + table:NS_HTML, tbody:NS_HTML, td:NS_HTML, template:NS_HTML, + textarea:NS_HTML, tfoot:NS_HTML, th:NS_HTML, thead:NS_HTML, title:NS_HTML, + tr:NS_HTML, track:NS_HTML, ul:NS_HTML, wbr:NS_HTML, xmp:NS_HTML, # MathML: mi:NS_MATHML, mo:NS_MATHML, mn:NS_MATHML, ms:NS_MATHML, mtext:NS_MATHML, @@ -648,7 +655,7 @@ parse_html = (args) -> for t in open_els if t.name is tag_name and (namespace is null or namespace is t.namespace) return true - if t.ns isnt NS_HTML and t.name isnt 'optgroup' and t.name isnt 'option' + if t.namespace isnt NS_HTML and t.name isnt 'optgroup' and t.name isnt 'option' return false return false # this checks for a particular element, not by name @@ -1663,10 +1670,10 @@ parse_html = (args) -> 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.namespace is NS_HTML return unless second.name is 'body' return if template_tag_is_open() - frameset_ok_flag = false + flag_frameset_ok = false for a of t.attrs_a second.attrs[a[0]] = a[1] unless second.attrs[a[0]]? return @@ -1675,9 +1682,10 @@ parse_html = (args) -> return if open_els.length < 2 second_i = open_els.length - 2 second = open_els[second_i] - return unless second.ns is NS_HTML + return unless second.namespace is NS_HTML return unless second.name is 'body' - flag_frameset_ok = false + if flag_frameset_ok is false + return if second.parent? for el, i in second.parent.children if el is second @@ -2098,20 +2106,37 @@ parse_html = (args) -> reconstruct_afe() insert_html_element t return - if t.type is TYPE_START_TAG and (t.name is 'rb' or t.name is 'rp' or t.name is 'rtc') +# this comment block implements the W3C spec +# if t.type is TYPE_START_TAG and (t.name is 'rb' or t.name is 'rp' or t.name is 'rtc') +# if is_in_scope 'ruby', NS_HTML +# generate_implied_end_tags() +# unless open_els[0].name is 'ruby' and open_els[0].namespace is NS_HTML +# parse_error() +# insert_html_element t +# return +# if t.type is TYPE_START_TAG and t.name is 'rt' +# if is_in_scope 'ruby', NS_HTML +# generate_implied_end_tags 'rtc' # arg is exception +# unless (open_els[0].name is 'ruby' or open_els[0].name is 'rtc') and open_els[0].namespace is NS_HTML +# parse_error() +# insert_html_element t +# return +# below implements the WATWG spec https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody + if t.type is TYPE_START_TAG and (t.name is 'rb' or t.name is 'rtc') if is_in_scope 'ruby', NS_HTML generate_implied_end_tags() unless open_els[0].name is 'ruby' and open_els[0].namespace is NS_HTML parse_error() insert_html_element t return - if t.type is TYPE_START_TAG and t.name is 'rt' + if t.type is TYPE_START_TAG and (t.name is 'rp' or t.name is 'rt') if is_in_scope 'ruby', NS_HTML - generate_implied_end_tags 'rtc' # arg is exception + generate_implied_end_tags 'rtc' unless (open_els[0].name is 'ruby' or open_els[0].name is 'rtc') and open_els[0].namespace is NS_HTML parse_error() insert_html_element t return +# end WATWG chunk if t.type is TYPE_START_TAG and t.name is 'math' reconstruct_afe() adjust_mathml_attributes t @@ -2180,7 +2205,8 @@ parse_html = (args) -> ins_mode_in_table = (t) -> switch t.type when TYPE_TEXT - 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' + if (open_els[0].name is 'table' or open_els[0].name is 'tbody' or open_els[0].name is 'tfoot' or open_els[0].name is 'thead' or open_els[0].name is 'tr') and open_els[0].namespace is NS_HTML + pending_table_character_tokens = [] original_ins_mode = ins_mode ins_mode = ins_mode_in_table_text process_token t @@ -2270,7 +2296,7 @@ parse_html = (args) -> # 8.2.5.4.10 http://www.w3.org/TR/html5/syntax.html#parsing-main-intabletext ins_mode_in_table_text = (t) -> if t.type is TYPE_TEXT and t.text is "\u0000" - # huh? I thought the tokenizer didn't emit these + # from javascript? parse_error() return if t.type is TYPE_TEXT @@ -2287,8 +2313,8 @@ parse_html = (args) -> insert_character old else for old in pending_table_character_tokens - ins_mode_table_else old - pending_table_character_tokens = [] # FIXME test (spec doesn't say this) + ins_mode_in_table_else old + pending_table_character_tokens = [] ins_mode = original_ins_mode process_token t @@ -2895,7 +2921,7 @@ parse_html = (args) -> tok_state = tok_state_tag_open when "\u0000" parse_error() - return new_text_node c + return new_text_node "\ufffd" when '' # EOF return new_eof_token() else @@ -3744,7 +3770,7 @@ parse_html = (args) -> else val = txt.substr cur, (next_gt - cur) cur = next_gt + 1 - val = val.replace "\u0000", "\ufffd" + val = val.replace(new RegExp("\u0000", 'g'), "\ufffd") tok_cur_tag.text += val tok_state = tok_state_data return tok_cur_tag @@ -4340,9 +4366,6 @@ parse_html = (args) -> else val = txt.substr cur, (next_gt - cur) cur = next_gt + 3 - val = val.replace(new RegExp("\u0000", 'g'), "\ufffd") # fixfull spec doesn't say this - val = val.replace(new RegExp("\r\n", 'g'), "\n") # fixfull spec doesn't say this - val = val.replace(new RegExp("\r", 'g'), "\n") # fixfull spec doesn't say this return new_character_token val # fixfull split # 8.2.4.69 http://www.w3.org/TR/html5/syntax.html#consume-a-character-reference @@ -4458,7 +4481,13 @@ parse_html = (args) -> # tokenizer initialization tok_state = tok_state_data - if args.name is "namespace-sensitivity.dat #1" + # text pre-processing + # FIXME http://www.w3.org/TR/html5/syntax.html#preprocessing-the-input-stream + txt = txt.replace(new RegExp("\u0000", 'g'), "\ufffd") # fixfull spec doesn't say this + txt = txt.replace(new RegExp("\r\n", 'g'), "\n") # fixfull spec doesn't say this + txt = txt.replace(new RegExp("\r", 'g'), "\n") # fixfull spec doesn't say this + + if args.name is "plain-text-unsafe.dat #4" console.log "hi" # proccess input # http://www.w3.org/TR/html5/syntax.html#tree-construction