1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00

Add an :escape_attrs option.

Closes gh-298
This commit is contained in:
Nathan Weizenbaum 2010-10-11 21:05:53 -07:00
parent 13f065cfd7
commit 64d6bf3c74
7 changed files with 63 additions and 11 deletions

View file

@ -8,6 +8,11 @@
* Don't add a `type` attribute to `<script>` and `<style>` tags generated by filters
when `:format` is set to `:html5`.
* Add an {file:HAML_REFERENCE.md#escape_attrs-option `:escape_attrs` option}
that allows attributes to either remain unescaped
(for things like embedding PHP directives in Haml)
or to be always escaped rather than `#escape_once`d.
### Backwards Incompatibilities -- Must Read!
* Get rid of the `--rails` flag for the `haml` executable.

View file

@ -143,6 +143,14 @@ Available options are:
See also [Escaping HTML](#escaping_html) and [Unescaping HTML](#unescaping_html)
Defaults to false.
{#escape_attrs-option} `:escape_attrs`
: Sets whether or not to escape HTML-sensitive characters in attributes.
If this is true, all HTML-sensitive characters in attributes are escaped.
If it's set to false, no HTML-sensitive characters in attributes are escaped.
If it's set to `:once`, existing HTML escape sequences are preserved,
but other HTML-sensitive characters are escaped.
Defaults to `:once`.
{#ugly-option} `:ugly`
: If set to `true`, Haml makes no attempt to properly
indent or format the HTML output.

View file

@ -209,7 +209,8 @@ RUBY
end) ? "" : "\n")
end
attributes = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes)
attributes = Precompiler.build_attributes(
html?, @options[:attr_wrapper], @options[:escape_attrs], attributes)
@buffer << "#{nuke_outer_whitespace || @options[:ugly] ? '' : tabs(tabulation)}<#{name}#{attributes}#{str}"
if content

View file

@ -84,6 +84,7 @@ module Haml
:ugly => false,
:format => :xhtml,
:escape_html => false,
:escape_attrs => true,
}
@ -294,6 +295,7 @@ module Haml
:format => @options[:format],
:encoding => @options[:encoding],
:escape_html => @options[:escape_html],
:escape_attrs => @options[:escape_attrs],
}
end

View file

@ -447,6 +447,7 @@ MESSAGE
attributes = Haml::Precompiler.build_attributes(haml_buffer.html?,
haml_buffer.options[:attr_wrapper],
haml_buffer.options[:escape_attrs],
attrs)
if text.nil? && block.nil? && (haml_buffer.options[:autoclose].include?(name) || flags.include?(:/))

View file

@ -523,7 +523,7 @@ END
end
# This is a class method so it can be accessed from Buffer.
def self.build_attributes(is_html, attr_wrapper, attributes = {})
def self.build_attributes(is_html, attr_wrapper, escape_attrs, attributes = {})
quote_escape = attr_wrapper == '"' ? "&quot;" : "&apos;"
other_quote_char = attr_wrapper == '"' ? "'" : '"'
@ -546,16 +546,28 @@ END
next
end
value = Haml::Helpers.preserve(Haml::Helpers.escape_once(value.to_s))
# We want to decide whether or not to escape quotes
value.gsub!('&quot;', '"')
this_attr_wrapper = attr_wrapper
if value.include? attr_wrapper
if value.include? other_quote_char
value = value.gsub(attr_wrapper, quote_escape)
escaped =
if escape_attrs == :once
Haml::Helpers.escape_once(value.to_s)
elsif escape_attrs
CGI.escapeHTML(value.to_s)
else
this_attr_wrapper = other_quote_char
value.to_s
end
value = Haml::Helpers.preserve(escaped)
if escape_attrs
# We want to decide whether or not to escape quotes
value.gsub!('&quot;', '"')
this_attr_wrapper = attr_wrapper
if value.include? attr_wrapper
if value.include? other_quote_char
value = value.gsub(attr_wrapper, quote_escape)
else
this_attr_wrapper = other_quote_char
end
end
else
this_attr_wrapper = attr_wrapper
end
" #{attr}=#{this_attr_wrapper}#{value}#{this_attr_wrapper}"
end
@ -570,7 +582,8 @@ END
end
def prerender_tag(name, self_close, attributes)
attributes_string = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes)
attributes_string = Precompiler.build_attributes(
html?, @options[:attr_wrapper], @options[:escape_attrs], attributes)
"<#{name}#{attributes_string}#{self_close && xhtml? ? ' /' : ''}>"
end

View file

@ -563,6 +563,28 @@ HTML
HAML
end
def test_escape_attrs_false
assert_equal(<<HTML, render(<<HAML, :escape_attrs => false))
<div class='<?php echo "&quot;" ?>' id='foo'>
bar
</div>
HTML
#foo{:class => '<?php echo "&quot;" ?>'}
bar
HAML
end
def test_escape_attrs_always
assert_equal(<<HTML, render(<<HAML, :escape_attrs => :always))
<div class='"&amp;lt;&amp;gt;&amp;amp;"' id='foo'>
bar
</div>
HTML
#foo{:class => '"&lt;&gt;&amp;"'}
bar
HAML
end
def test_escape_html
html = <<HTML
&amp;