Allows custom styles in textile formatting using a white list of styles (#2416).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@8860 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
e14a9f5503
commit
0ede069d2c
|
@ -474,7 +474,10 @@ class RedCloth3 < String
|
||||||
style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
|
style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN
|
||||||
end
|
end
|
||||||
|
|
||||||
style << "#{ htmlesc $1 };" if text.sub!( /\{([^}]*)\}/, '' ) && !filter_styles
|
if text.sub!( /\{([^"}]*)\}/, '' ) && !filter_styles
|
||||||
|
sanitized = sanitize_styles($1)
|
||||||
|
style << "#{ sanitized };" unless sanitized.blank?
|
||||||
|
end
|
||||||
|
|
||||||
lang = $1 if
|
lang = $1 if
|
||||||
text.sub!( /\[([^)]+?)\]/, '' )
|
text.sub!( /\[([^)]+?)\]/, '' )
|
||||||
|
@ -502,6 +505,16 @@ class RedCloth3 < String
|
||||||
atts
|
atts
|
||||||
end
|
end
|
||||||
|
|
||||||
|
STYLES_RE = /^(color|width|height|border|background|padding|margin|font|text)(-[a-z]+)*:\s*((\d+%?|\d+px|\d+(\.\d+)?em|#[0-9a-f]+|[a-z]+)\s*)+$/i
|
||||||
|
|
||||||
|
def sanitize_styles(str)
|
||||||
|
styles = str.split(";").map(&:strip)
|
||||||
|
styles.reject! do |style|
|
||||||
|
!style.match(STYLES_RE)
|
||||||
|
end
|
||||||
|
styles.join(";")
|
||||||
|
end
|
||||||
|
|
||||||
TABLE_RE = /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m
|
TABLE_RE = /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m
|
||||||
|
|
||||||
# Parses a Textile table block, building HTML from the result.
|
# Parses a Textile table block, building HTML from the result.
|
||||||
|
|
|
@ -31,7 +31,7 @@ module Redmine
|
||||||
super
|
super
|
||||||
self.hard_breaks=true
|
self.hard_breaks=true
|
||||||
self.no_span_caps=true
|
self.no_span_caps=true
|
||||||
self.filter_styles=true
|
self.filter_styles=false
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_html(*rules)
|
def to_html(*rules)
|
||||||
|
|
|
@ -59,6 +59,50 @@ class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_styles
|
||||||
|
# single style
|
||||||
|
assert_html_output({
|
||||||
|
'p{color:red}. text' => '<p style="color:red;">text</p>',
|
||||||
|
'p{color:red;}. text' => '<p style="color:red;">text</p>',
|
||||||
|
'p{color: red}. text' => '<p style="color: red;">text</p>',
|
||||||
|
'p{color:#f00}. text' => '<p style="color:#f00;">text</p>',
|
||||||
|
'p{color:#ff0000}. text' => '<p style="color:#ff0000;">text</p>',
|
||||||
|
'p{border:10px}. text' => '<p style="border:10px;">text</p>',
|
||||||
|
'p{border:10}. text' => '<p style="border:10;">text</p>',
|
||||||
|
'p{border:10%}. text' => '<p style="border:10%;">text</p>',
|
||||||
|
'p{border:10em}. text' => '<p style="border:10em;">text</p>',
|
||||||
|
'p{border:1.5em}. text' => '<p style="border:1.5em;">text</p>',
|
||||||
|
'p{border-left:1px}. text' => '<p style="border-left:1px;">text</p>',
|
||||||
|
'p{border-right:1px}. text' => '<p style="border-right:1px;">text</p>',
|
||||||
|
'p{border-top:1px}. text' => '<p style="border-top:1px;">text</p>',
|
||||||
|
'p{border-bottom:1px}. text' => '<p style="border-bottom:1px;">text</p>',
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
# multiple styles
|
||||||
|
assert_html_output({
|
||||||
|
'p{color:red; border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>',
|
||||||
|
'p{color:red ; border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>',
|
||||||
|
'p{color:red;border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>',
|
||||||
|
}, false)
|
||||||
|
|
||||||
|
# styles with multiple values
|
||||||
|
assert_html_output({
|
||||||
|
'p{border:1px solid red;}. text' => '<p style="border:1px solid red;">text</p>',
|
||||||
|
'p{border-top-left-radius: 10px 5px;}. text' => '<p style="border-top-left-radius: 10px 5px;">text</p>',
|
||||||
|
}, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_invalid_styles_should_be_filtered
|
||||||
|
assert_html_output({
|
||||||
|
'p{invalid}. text' => '<p>text</p>',
|
||||||
|
'p{invalid:red}. text' => '<p>text</p>',
|
||||||
|
'p{color:(red)}. text' => '<p>text</p>',
|
||||||
|
'p{color:red;invalid:blue}. text' => '<p style="color:red;">text</p>',
|
||||||
|
'p{invalid:blue;color:red}. text' => '<p style="color:red;">text</p>',
|
||||||
|
'p{color:"}. text' => '<p>text</p>',
|
||||||
|
}, false)
|
||||||
|
end
|
||||||
|
|
||||||
def test_inline_code
|
def test_inline_code
|
||||||
assert_html_output(
|
assert_html_output(
|
||||||
'this is @some code@' => 'this is <code>some code</code>',
|
'this is @some code@' => 'this is <code>some code</code>',
|
||||||
|
|
Loading…
Reference in New Issue