@@ -474,7 +474,10 class RedCloth3 < String | |||||
474 | style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN |
|
474 | style << "vertical-align:#{ v_align( $& ) };" if text =~ A_VLGN | |
475 | end |
|
475 | end | |
476 |
|
476 | |||
477 |
|
|
477 | if text.sub!( /\{([^"}]*)\}/, '' ) && !filter_styles | |
|
478 | sanitized = sanitize_styles($1) | |||
|
479 | style << "#{ sanitized };" unless sanitized.blank? | |||
|
480 | end | |||
478 |
|
481 | |||
479 | lang = $1 if |
|
482 | lang = $1 if | |
480 | text.sub!( /\[([^)]+?)\]/, '' ) |
|
483 | text.sub!( /\[([^)]+?)\]/, '' ) | |
@@ -502,6 +505,16 class RedCloth3 < String | |||||
502 | atts |
|
505 | atts | |
503 | end |
|
506 | end | |
504 |
|
507 | |||
|
508 | 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 | |||
|
509 | ||||
|
510 | def sanitize_styles(str) | |||
|
511 | styles = str.split(";").map(&:strip) | |||
|
512 | styles.reject! do |style| | |||
|
513 | !style.match(STYLES_RE) | |||
|
514 | end | |||
|
515 | styles.join(";") | |||
|
516 | end | |||
|
517 | ||||
505 | TABLE_RE = /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m |
|
518 | TABLE_RE = /^(?:table(_?#{S}#{A}#{C})\. ?\n)?^(#{A}#{C}\.? ?\|.*?\|)(\n\n|\Z)/m | |
506 |
|
519 | |||
507 | # Parses a Textile table block, building HTML from the result. |
|
520 | # Parses a Textile table block, building HTML from the result. |
@@ -31,7 +31,7 module Redmine | |||||
31 | super |
|
31 | super | |
32 | self.hard_breaks=true |
|
32 | self.hard_breaks=true | |
33 | self.no_span_caps=true |
|
33 | self.no_span_caps=true | |
34 |
self.filter_styles= |
|
34 | self.filter_styles=false | |
35 | end |
|
35 | end | |
36 |
|
36 | |||
37 | def to_html(*rules) |
|
37 | def to_html(*rules) |
@@ -59,6 +59,50 class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase | |||||
59 | end |
|
59 | end | |
60 | end |
|
60 | end | |
61 |
|
61 | |||
|
62 | def test_styles | |||
|
63 | # single style | |||
|
64 | assert_html_output({ | |||
|
65 | 'p{color:red}. text' => '<p style="color:red;">text</p>', | |||
|
66 | 'p{color:red;}. text' => '<p style="color:red;">text</p>', | |||
|
67 | 'p{color: red}. text' => '<p style="color: red;">text</p>', | |||
|
68 | 'p{color:#f00}. text' => '<p style="color:#f00;">text</p>', | |||
|
69 | 'p{color:#ff0000}. text' => '<p style="color:#ff0000;">text</p>', | |||
|
70 | 'p{border:10px}. text' => '<p style="border:10px;">text</p>', | |||
|
71 | 'p{border:10}. text' => '<p style="border:10;">text</p>', | |||
|
72 | 'p{border:10%}. text' => '<p style="border:10%;">text</p>', | |||
|
73 | 'p{border:10em}. text' => '<p style="border:10em;">text</p>', | |||
|
74 | 'p{border:1.5em}. text' => '<p style="border:1.5em;">text</p>', | |||
|
75 | 'p{border-left:1px}. text' => '<p style="border-left:1px;">text</p>', | |||
|
76 | 'p{border-right:1px}. text' => '<p style="border-right:1px;">text</p>', | |||
|
77 | 'p{border-top:1px}. text' => '<p style="border-top:1px;">text</p>', | |||
|
78 | 'p{border-bottom:1px}. text' => '<p style="border-bottom:1px;">text</p>', | |||
|
79 | }, false) | |||
|
80 | ||||
|
81 | # multiple styles | |||
|
82 | assert_html_output({ | |||
|
83 | 'p{color:red; border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>', | |||
|
84 | 'p{color:red ; border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>', | |||
|
85 | 'p{color:red;border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>', | |||
|
86 | }, false) | |||
|
87 | ||||
|
88 | # styles with multiple values | |||
|
89 | assert_html_output({ | |||
|
90 | 'p{border:1px solid red;}. text' => '<p style="border:1px solid red;">text</p>', | |||
|
91 | 'p{border-top-left-radius: 10px 5px;}. text' => '<p style="border-top-left-radius: 10px 5px;">text</p>', | |||
|
92 | }, false) | |||
|
93 | end | |||
|
94 | ||||
|
95 | def test_invalid_styles_should_be_filtered | |||
|
96 | assert_html_output({ | |||
|
97 | 'p{invalid}. text' => '<p>text</p>', | |||
|
98 | 'p{invalid:red}. text' => '<p>text</p>', | |||
|
99 | 'p{color:(red)}. text' => '<p>text</p>', | |||
|
100 | 'p{color:red;invalid:blue}. text' => '<p style="color:red;">text</p>', | |||
|
101 | 'p{invalid:blue;color:red}. text' => '<p style="color:red;">text</p>', | |||
|
102 | 'p{color:"}. text' => '<p>text</p>', | |||
|
103 | }, false) | |||
|
104 | end | |||
|
105 | ||||
62 | def test_inline_code |
|
106 | def test_inline_code | |
63 | assert_html_output( |
|
107 | assert_html_output( | |
64 | 'this is @some code@' => 'this is <code>some code</code>', |
|
108 | 'this is @some code@' => 'this is <code>some code</code>', |
General Comments 0
You need to be logged in to leave comments.
Login now