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:
parent
13f065cfd7
commit
64d6bf3c74
7 changed files with 63 additions and 11 deletions
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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?(:/))
|
||||
|
|
|
@ -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 == '"' ? """ : "'"
|
||||
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!('"', '"')
|
||||
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!('"', '"')
|
||||
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
|
||||
|
||||
|
|
|
@ -563,6 +563,28 @@ HTML
|
|||
HAML
|
||||
end
|
||||
|
||||
def test_escape_attrs_false
|
||||
assert_equal(<<HTML, render(<<HAML, :escape_attrs => false))
|
||||
<div class='<?php echo """ ?>' id='foo'>
|
||||
bar
|
||||
</div>
|
||||
HTML
|
||||
#foo{:class => '<?php echo """ ?>'}
|
||||
bar
|
||||
HAML
|
||||
end
|
||||
|
||||
def test_escape_attrs_always
|
||||
assert_equal(<<HTML, render(<<HAML, :escape_attrs => :always))
|
||||
<div class='"&lt;&gt;&amp;"' id='foo'>
|
||||
bar
|
||||
</div>
|
||||
HTML
|
||||
#foo{:class => '"<>&"'}
|
||||
bar
|
||||
HAML
|
||||
end
|
||||
|
||||
def test_escape_html
|
||||
html = <<HTML
|
||||
&
|
||||
|
|
Loading…
Reference in a new issue