Use separate Ragel machines for script/style tags

Previously a single Ragel machine was used for processing HTML
script and style tags. This had the unfortunate side-effect that the
following was not parsed correctly (while being valid HTML):

    <script>
    var foo = "</style>";
    </script>

The same applied to style tags:

    <style>
    /* </script> */
    </style>

By using separate machines we can work around the above issue. The
downside is that this can produce multiple T_TEXT nodes, which have to
be stitched back together in the parser.
This commit is contained in:
Yorick Peterse committed 2015-04-16 01:45:39 +02:00
1 parent 2d43e459a1
commit 73fbbfbdbd
7 files changed
+118 -54

No files matched your search

+16 -5
View File
@@ -40,12 +40,18 @@ module Oga
class Lexer
attr_reader :html
# @return [String]
HTML_SCRIPT = 'script'
# @return [String]
HTML_STYLE = 'style'
##
# Names of HTML tags of which the content should be lexed as-is.
#
# @return [Array]
#
LITERAL_HTML_ELEMENTS = %w{script style}
LITERAL_HTML_ELEMENTS = [HTML_SCRIPT, HTML_STYLE]
##
# @param [String|IO] data The data to lex. This can either be a String or
@@ -189,12 +195,17 @@ module Oga
end
##
# Returns true if the current element's content should be lexed as-is.
#
# @return [TrueClass|FalseClass]
#
def literal_html_element?
return html? && LITERAL_HTML_ELEMENTS.include?(current_element)
def html_script?
return html? && current_element == HTML_SCRIPT
end
##
# @return [TrueClass|FalseClass]
#
def html_style?
return html? && current_element == HTML_STYLE
end
##
+11 -1
View File
@@ -176,7 +176,17 @@ xml_decl
# Plain text
text
= T_TEXT { on_text(val[0]) }
= T_TEXT text_follow
{
text = val[1] ? val[0] + val[1] : val[0]
on_text(text)
}
;
text_follow
= T_TEXT text_follow { val[1] ? val[0] + val[1] : val[0] }
| _ { nil }
;
# Strings