Don't convert entities in script/style elements

In HTML the text of a script/style tag should be left untouched, no
entities must be converted. Doing so would break Javascript such as the
following:

    foo&&bar;

Such code is often the result of minifiers doing their dirty business.
This commit is contained in:
Yorick Peterse 2015-04-08 14:30:02 +02:00
parent 6a1010c287
commit 4bdc8a3fdc
2 changed files with 53 additions and 7 deletions

View File

@ -26,7 +26,7 @@ module Oga
# @return [String] # @return [String]
# #
def text def text
unless @decoded if decode_entities?
@text = EntityDecoder.try_decode(@text, html?) @text = EntityDecoder.try_decode(@text, html?)
@decoded = true @decoded = true
end end
@ -38,15 +38,29 @@ module Oga
# @see [Oga::XML::CharacterNode#to_xml] # @see [Oga::XML::CharacterNode#to_xml]
# #
def to_xml def to_xml
node = parent return super if inside_literal_html?
if node.is_a?(Element) and html? \
and Lexer::LITERAL_HTML_ELEMENTS.include?(node.name)
return super
end
return Entities.encode(super) return Entities.encode(super)
end end
private
##
# @return [TrueClass|FalseClass]
#
def decode_entities?
return !@decoded && !inside_literal_html?
end
##
# @return [TrueClass|FalseClass]
#
def inside_literal_html?
node = parent
return node.is_a?(Element) && html? &&
Lexer::LITERAL_HTML_ELEMENTS.include?(node.name)
end
end # Text end # Text
end # XML end # XML
end # Oga end # Oga

View File

@ -85,6 +85,38 @@ describe Oga::XML::Text do
node.text.should == [160].pack('U') node.text.should == [160].pack('U')
end end
end end
describe 'inside an HTML script element' do
before do
@element = Oga::XML::Element.new(:name => 'script')
@document = Oga::XML::Document.new(
:type => :html,
:children => [@element]
)
end
it 'does not decode any entities' do
@element.inner_text = '&foo;'
@element.inner_text.should == '&foo;'
end
end
describe 'inside an HTML style element' do
before do
@element = Oga::XML::Element.new(:name => 'style')
@document = Oga::XML::Document.new(
:type => :html,
:children => [@element]
)
end
it 'does not decode any entities' do
@element.inner_text = '&foo;'
@element.inner_text.should == '&foo;'
end
end
end end
describe '#to_xml' do describe '#to_xml' do