haml-edge 2.3.209 → 2.3.210
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +2 -0
- data/EDGE_GEM_VERSION +1 -1
- data/Rakefile +24 -2
- data/VERSION +1 -1
- data/lib/haml/exec.rb +11 -4
- data/lib/haml/filters.rb +3 -0
- data/lib/haml/helpers/action_view_extensions.rb +4 -2
- data/lib/haml/helpers/action_view_mods.rb +6 -4
- data/lib/haml/helpers.rb +2 -10
- data/lib/haml/html.rb +0 -1
- data/lib/haml/precompiler.rb +37 -30
- data/lib/haml/railtie.rb +6 -2
- data/lib/haml/root.rb +4 -0
- data/lib/haml/template.rb +2 -0
- data/lib/haml/util/subset_map.rb +101 -0
- data/lib/haml/util.rb +74 -0
- data/lib/haml.rb +5 -2
- data/lib/sass/engine.rb +36 -31
- data/lib/sass/files.rb +1 -1
- data/lib/sass/plugin/staleness_checker.rb +9 -9
- data/lib/sass/plugin.rb +21 -0
- data/lib/sass/script/color.rb +4 -3
- data/lib/sass/script/css_lexer.rb +11 -1
- data/lib/sass/script/css_parser.rb +4 -1
- data/lib/sass/script/funcall.rb +9 -0
- data/lib/sass/script/interpolation.rb +21 -0
- data/lib/sass/script/lexer.rb +30 -13
- data/lib/sass/script/node.rb +1 -1
- data/lib/sass/script/number.rb +4 -5
- data/lib/sass/script/parser.rb +13 -14
- data/lib/sass/script/string.rb +8 -2
- data/lib/sass/script/string_interpolation.rb +27 -4
- data/lib/sass/script.rb +1 -2
- data/lib/sass/scss/css_parser.rb +5 -3
- data/lib/sass/scss/parser.rb +146 -64
- data/lib/sass/scss/rx.rb +9 -1
- data/lib/sass/scss/sass_parser.rb +11 -0
- data/lib/sass/scss/script_lexer.rb +2 -0
- data/lib/sass/scss/static_parser.rb +48 -0
- data/lib/sass/scss.rb +3 -0
- data/lib/sass/selector/abstract_sequence.rb +40 -0
- data/lib/sass/selector/comma_sequence.rb +80 -0
- data/lib/sass/selector/sequence.rb +194 -0
- data/lib/sass/selector/simple.rb +107 -0
- data/lib/sass/selector/simple_sequence.rb +161 -0
- data/lib/sass/selector.rb +353 -0
- data/lib/sass/tree/comment_node.rb +1 -0
- data/lib/sass/tree/debug_node.rb +1 -0
- data/lib/sass/tree/directive_node.rb +1 -0
- data/lib/sass/tree/extend_node.rb +60 -0
- data/lib/sass/tree/for_node.rb +1 -0
- data/lib/sass/tree/if_node.rb +2 -0
- data/lib/sass/tree/import_node.rb +2 -0
- data/lib/sass/tree/mixin_def_node.rb +1 -0
- data/lib/sass/tree/mixin_node.rb +21 -5
- data/lib/sass/tree/node.rb +59 -12
- data/lib/sass/tree/prop_node.rb +20 -21
- data/lib/sass/tree/root_node.rb +8 -17
- data/lib/sass/tree/rule_node.rb +49 -100
- data/lib/sass/tree/variable_node.rb +1 -0
- data/lib/sass/tree/warn_node.rb +1 -0
- data/lib/sass/tree/while_node.rb +1 -0
- data/lib/sass.rb +1 -0
- data/test/haml/engine_test.rb +185 -3
- data/test/haml/helper_test.rb +25 -2
- data/test/haml/template_test.rb +2 -2
- data/test/haml/templates/helpers.haml +13 -0
- data/test/haml/util/subset_map_test.rb +91 -0
- data/test/haml/util_test.rb +25 -0
- data/test/sass/conversion_test.rb +23 -3
- data/test/sass/engine_test.rb +50 -7
- data/test/sass/extend_test.rb +1045 -0
- data/test/sass/results/complex.css +0 -1
- data/test/sass/results/script.css +1 -1
- data/test/sass/script_conversion_test.rb +16 -0
- data/test/sass/script_test.rb +37 -4
- data/test/sass/scss/css_test.rb +17 -3
- data/test/sass/scss/rx_test.rb +1 -1
- data/test/sass/scss/scss_test.rb +30 -0
- data/test/sass/templates/complex.sass +0 -2
- data/test/test_helper.rb +5 -0
- metadata +17 -3
data/lib/sass/tree/prop_node.rb
CHANGED
@@ -68,28 +68,19 @@ module Sass::Tree
|
|
68
68
|
# This only applies for old-style properties with no value,
|
69
69
|
# so returns the empty string if this is new-style.
|
70
70
|
#
|
71
|
-
# This should only be called once \{#perform} has been called.
|
72
|
-
#
|
73
71
|
# @return [String] The message
|
74
72
|
def pseudo_class_selector_message
|
75
|
-
return "" if @prop_syntax == :new || !
|
73
|
+
return "" if @prop_syntax == :new || !value.is_a?(Sass::Script::String) || !value.value.empty?
|
76
74
|
"\nIf #{declaration.dump} should be a selector, use \"\\#{declaration}\" instead."
|
77
75
|
end
|
78
76
|
|
79
77
|
protected
|
80
78
|
|
79
|
+
# @see Node#to_src
|
81
80
|
def to_src(tabs, opts, fmt)
|
82
|
-
|
83
|
-
if name[0] == ?:
|
84
|
-
raise Sass::SyntaxError.new("The \":#{name}: #{self.class.val_to_sass(value, opts)}\" hack is not allowed in the Sass indented syntax")
|
85
|
-
end
|
86
|
-
|
87
|
-
old = opts[:old] && fmt == :sass
|
88
|
-
initial = old ? ':' : ''
|
89
|
-
mid = old ? '' : ':'
|
90
|
-
res = "#{' ' * tabs}#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}"
|
81
|
+
res = declaration(tabs, opts, fmt)
|
91
82
|
return res + "#{semi fmt}\n" if children.empty?
|
92
|
-
res
|
83
|
+
res + children_to_src(tabs, opts, fmt).rstrip + semi(fmt) + "\n"
|
93
84
|
end
|
94
85
|
|
95
86
|
# Computes the CSS for the property.
|
@@ -103,10 +94,12 @@ module Sass::Tree
|
|
103
94
|
|
104
95
|
# Converts nested properties into flat properties.
|
105
96
|
#
|
97
|
+
# @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
98
|
+
# The extensions defined for this tree
|
106
99
|
# @param parent [PropNode, nil] The parent node of this node,
|
107
100
|
# or nil if the parent isn't a {PropNode}
|
108
101
|
# @raise [Sass::SyntaxError] if the property uses invalid syntax
|
109
|
-
def _cssize(parent)
|
102
|
+
def _cssize(extends, parent)
|
110
103
|
node = super
|
111
104
|
result = node.children.dup
|
112
105
|
if !node.resolved_value.empty? || node.children.empty?
|
@@ -119,9 +112,11 @@ module Sass::Tree
|
|
119
112
|
# Updates the name and indentation of this node based on the parent name
|
120
113
|
# and nesting level.
|
121
114
|
#
|
115
|
+
# @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
116
|
+
# The extensions defined for this tree
|
122
117
|
# @param parent [PropNode, nil] The parent node of this node,
|
123
118
|
# or nil if the parent isn't a {PropNode}
|
124
|
-
def cssize!(parent)
|
119
|
+
def cssize!(extends, parent)
|
125
120
|
self.resolved_name = "#{parent.resolved_name}-#{resolved_name}" if parent
|
126
121
|
self.tabs = parent.tabs + (parent.resolved_value.empty? ? 0 : 1) if parent && style == :nested
|
127
122
|
super
|
@@ -169,12 +164,16 @@ module Sass::Tree
|
|
169
164
|
end
|
170
165
|
end
|
171
166
|
|
172
|
-
def declaration
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
167
|
+
def declaration(tabs = 0, opts = {:old => @prop_syntax == :old}, fmt = :sass)
|
168
|
+
name = self.name.map {|n| n.is_a?(String) ? n : "\#{#{n.to_sass(opts)}}"}.join
|
169
|
+
if name[0] == ?:
|
170
|
+
raise Sass::SyntaxError.new("The \":#{name}: #{self.class.val_to_sass(value, opts)}\" hack is not allowed in the Sass indented syntax")
|
171
|
+
end
|
172
|
+
|
173
|
+
old = opts[:old] && fmt == :sass
|
174
|
+
initial = old ? ':' : ''
|
175
|
+
mid = old ? '' : ':'
|
176
|
+
"#{' ' * tabs}#{initial}#{name}#{mid} #{self.class.val_to_sass(value, opts)}".rstrip
|
178
177
|
end
|
179
178
|
|
180
179
|
class << self
|
data/lib/sass/tree/root_node.rb
CHANGED
@@ -62,6 +62,7 @@ module Sass
|
|
62
62
|
|
63
63
|
protected
|
64
64
|
|
65
|
+
# @see Node#to_src
|
65
66
|
def to_src(opts, fmt)
|
66
67
|
Haml::Util.enum_cons(children + [nil], 2).map do |child, nxt|
|
67
68
|
child.send("to_#{fmt}", 0, opts) +
|
@@ -75,20 +76,6 @@ module Sass
|
|
75
76
|
end.join.rstrip + "\n"
|
76
77
|
end
|
77
78
|
|
78
|
-
# Destructively converts this static Sass node into a static CSS node,
|
79
|
-
# and checks that there are no properties at root level.
|
80
|
-
#
|
81
|
-
# @param parent [Node, nil] The parent node of this node.
|
82
|
-
# This should only be non-nil if the parent is the same class as this node
|
83
|
-
# @see Node#cssize!
|
84
|
-
def cssize!(parent)
|
85
|
-
super
|
86
|
-
return unless child = children.find {|c| c.is_a?(PropNode)}
|
87
|
-
message = "Properties aren't allowed at the root of a document." +
|
88
|
-
child.pseudo_class_selector_message
|
89
|
-
raise Sass::SyntaxError.new(message, :line => child.line)
|
90
|
-
end
|
91
|
-
|
92
79
|
# Computes the CSS corresponding to this Sass tree.
|
93
80
|
#
|
94
81
|
# @param args [Array] ignored
|
@@ -106,12 +93,16 @@ module Sass
|
|
106
93
|
return result + "\n"
|
107
94
|
end
|
108
95
|
|
109
|
-
# Returns
|
110
|
-
#
|
96
|
+
# Returns an error message if the given child node is invalid,
|
97
|
+
# and false otherwise.
|
98
|
+
#
|
99
|
+
# Only property nodes are invalid at root level.
|
111
100
|
#
|
112
101
|
# @see Node#invalid_child?
|
113
102
|
def invalid_child?(child)
|
114
|
-
|
103
|
+
return unless child.is_a?(Tree::PropNode)
|
104
|
+
"Properties aren't allowed at the root of a document." +
|
105
|
+
child.pseudo_class_selector_message
|
115
106
|
end
|
116
107
|
end
|
117
108
|
end
|
data/lib/sass/tree/rule_node.rb
CHANGED
@@ -7,7 +7,6 @@ module Sass::Tree
|
|
7
7
|
# @see Sass::Tree
|
8
8
|
class RuleNode < Node
|
9
9
|
# The character used to include the parent selector
|
10
|
-
# @private
|
11
10
|
PARENT = '&'
|
12
11
|
|
13
12
|
# The CSS selector for this rule,
|
@@ -18,44 +17,19 @@ module Sass::Tree
|
|
18
17
|
# @return [Array<String, Sass::Script::Node>]
|
19
18
|
attr_accessor :rule
|
20
19
|
|
21
|
-
# The CSS
|
22
|
-
#
|
20
|
+
# The CSS selector for this rule,
|
21
|
+
# without any unresolved interpolation
|
22
|
+
# but with parent references still intact.
|
23
23
|
# It's only set once {Tree::Node#perform} has been called.
|
24
24
|
#
|
25
|
-
#
|
26
|
-
# The first level of arrays comma-separated selectors;
|
27
|
-
# the second represents structure within those selectors,
|
28
|
-
# currently only parent-refs (represented by `:parent`).
|
29
|
-
# Newlines are represented as literal `\n` characters in the strings.
|
30
|
-
# For example,
|
31
|
-
#
|
32
|
-
# &.foo, bar, baz,
|
33
|
-
# bip, &.bop, bup
|
34
|
-
#
|
35
|
-
# would be
|
36
|
-
#
|
37
|
-
# [[:parent, ".foo"], ["bar"], ["baz"],
|
38
|
-
# ["\nbip"], [:parent, ".bop"], ["bup"]]
|
39
|
-
#
|
40
|
-
# @return [Array<Array<String, Symbol>>]
|
25
|
+
# @return [Selector::CommaSequence]
|
41
26
|
attr_accessor :parsed_rules
|
42
27
|
|
43
|
-
# The CSS
|
44
|
-
#
|
28
|
+
# The CSS selector for this rule,
|
29
|
+
# without any unresolved interpolation or parent references.
|
45
30
|
# It's only set once {Tree::Node#cssize} has been called.
|
46
31
|
#
|
47
|
-
#
|
48
|
-
# Newlines are represented as literal `\n` characters in the strings.
|
49
|
-
# For example,
|
50
|
-
#
|
51
|
-
# foo bar, baz,
|
52
|
-
# bang, bip bop, blip
|
53
|
-
#
|
54
|
-
# would be
|
55
|
-
#
|
56
|
-
# ["foo bar", "baz", "\nbang", "bip bop", "blip"]
|
57
|
-
#
|
58
|
-
# @return [Array<String>]
|
32
|
+
# @return [Selector::CommaSequence]
|
59
33
|
attr_accessor :resolved_rules
|
60
34
|
|
61
35
|
# How deep this rule is indented
|
@@ -121,6 +95,7 @@ module Sass::Tree
|
|
121
95
|
name.gsub(/^/, ' ' * tabs) + children_to_src(tabs, opts, :sass)
|
122
96
|
end
|
123
97
|
|
98
|
+
# @see Node#to_scss
|
124
99
|
def to_scss(tabs, opts = {})
|
125
100
|
name = rule.map {|r| r.is_a?(String) ? r : "\#{#{r.to_sass(opts)}}"}.
|
126
101
|
join.gsub(/^[ \t]*/, ' ' * tabs)
|
@@ -135,6 +110,15 @@ module Sass::Tree
|
|
135
110
|
res
|
136
111
|
end
|
137
112
|
|
113
|
+
# Extends this Rule's selector with the given `extends`.
|
114
|
+
#
|
115
|
+
# @see Node#do_extend
|
116
|
+
def do_extend(extends)
|
117
|
+
node = dup
|
118
|
+
node.resolved_rules = resolved_rules.do_extend(extends)
|
119
|
+
node
|
120
|
+
end
|
121
|
+
|
138
122
|
protected
|
139
123
|
|
140
124
|
# Computes the CSS for the rule.
|
@@ -154,7 +138,9 @@ module Sass::Tree
|
|
154
138
|
rule_indent = ' ' * (tabs - 1)
|
155
139
|
per_rule_indent, total_indent = [:nested, :expanded].include?(style) ? [rule_indent, ''] : ['', rule_indent]
|
156
140
|
|
157
|
-
total_rule = total_indent + resolved_rules.
|
141
|
+
total_rule = total_indent + resolved_rules.members.
|
142
|
+
map {|seq| seq.to_a.join}.
|
143
|
+
join(rule_separator).split("\n").map do |line|
|
158
144
|
per_rule_indent + line.strip
|
159
145
|
end.join(line_separator)
|
160
146
|
|
@@ -199,21 +185,24 @@ module Sass::Tree
|
|
199
185
|
to_return
|
200
186
|
end
|
201
187
|
|
202
|
-
# Runs
|
203
|
-
# and parses the
|
188
|
+
# Runs SassScript interpolation in the selector,
|
189
|
+
# and then parses the result into a {Sass::Selector::CommaSequence}.
|
204
190
|
#
|
205
191
|
# @param environment [Sass::Environment] The lexical environment containing
|
206
192
|
# variable and mixin values
|
207
193
|
def perform!(environment)
|
208
|
-
@parsed_rules =
|
194
|
+
@parsed_rules = Sass::SCSS::StaticParser.new(run_interp(@rule, environment)).
|
195
|
+
parse_selector(self.line, self.filename)
|
209
196
|
super
|
210
197
|
end
|
211
198
|
|
212
199
|
# Converts nested rules into a flat list of rules.
|
213
200
|
#
|
201
|
+
# @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
202
|
+
# The extensions defined for this tree
|
214
203
|
# @param parent [RuleNode, nil] The parent node of this node,
|
215
204
|
# or nil if the parent isn't a {RuleNode}
|
216
|
-
def _cssize(parent)
|
205
|
+
def _cssize(extends, parent)
|
217
206
|
node = super
|
218
207
|
rules = node.children.select {|c| c.is_a?(RuleNode)}
|
219
208
|
props = node.children.reject {|c| c.is_a?(RuleNode) || c.invisible?}
|
@@ -232,14 +221,28 @@ module Sass::Tree
|
|
232
221
|
# Resolves parent references and nested selectors,
|
233
222
|
# and updates the indentation based on the parent's indentation.
|
234
223
|
#
|
224
|
+
# @param extends [Haml::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
|
225
|
+
# The extensions defined for this tree
|
235
226
|
# @param parent [RuleNode, nil] The parent node of this node,
|
236
227
|
# or nil if the parent isn't a {RuleNode}
|
237
228
|
# @raise [Sass::SyntaxError] if the rule has no parents but uses `&`
|
238
|
-
def cssize!(parent)
|
239
|
-
self.resolved_rules = resolve_parent_refs(parent && parent.resolved_rules)
|
229
|
+
def cssize!(extends, parent)
|
230
|
+
self.resolved_rules = @parsed_rules.resolve_parent_refs(parent && parent.resolved_rules)
|
240
231
|
super
|
241
232
|
end
|
242
233
|
|
234
|
+
# Returns an error message if the given child node is invalid,
|
235
|
+
# and false otherwise.
|
236
|
+
#
|
237
|
+
# {ExtendNode}s are valid within {RuleNode}s.
|
238
|
+
#
|
239
|
+
# @param child [Tree::Node] A potential child nodecompact.
|
240
|
+
# @return [Boolean, String] Whether or not the child node is valid,
|
241
|
+
# as well as the error message to display if it is invalid
|
242
|
+
def invalid_child?(child)
|
243
|
+
super unless child.is_a?(ExtendNode)
|
244
|
+
end
|
245
|
+
|
243
246
|
# A hash that will be associated with this rule in the CSS document
|
244
247
|
# if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled.
|
245
248
|
# This data is used by e.g. [the FireSass Firebug extension](https://addons.mozilla.org/en-US/firefox/addon/103988).
|
@@ -252,70 +255,16 @@ module Sass::Tree
|
|
252
255
|
|
253
256
|
private
|
254
257
|
|
255
|
-
def resolve_parent_refs(super_rules)
|
256
|
-
if super_rules.nil?
|
257
|
-
return @parsed_rules.map do |rule|
|
258
|
-
if rule.include?(:parent)
|
259
|
-
raise Sass::SyntaxError.new("Base-level rules cannot contain the parent-selector-referencing character '#{PARENT}'.")
|
260
|
-
end
|
261
|
-
|
262
|
-
rule.join
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
new_rules = []
|
267
|
-
super_rules.each do |super_rule|
|
268
|
-
@parsed_rules.each do |rule|
|
269
|
-
new_rules << []
|
270
|
-
|
271
|
-
# An initial newline of the child rule
|
272
|
-
# should be moved to the beginning of the entire rule
|
273
|
-
rule.first.slice!(0) if nl = (rule.first.is_a?(String) && rule.first[0] == ?\n)
|
274
|
-
rule = [nl ? "\n" : "", :parent, " ", *rule] unless rule.include?(:parent)
|
275
|
-
|
276
|
-
new_rules.last << rule.map do |segment|
|
277
|
-
next segment unless segment == :parent
|
278
|
-
super_rule
|
279
|
-
end.join
|
280
|
-
end
|
281
|
-
end
|
282
|
-
new_rules
|
283
|
-
end
|
284
|
-
|
285
|
-
def parse_selector(text)
|
286
|
-
scanner = StringScanner.new(text)
|
287
|
-
rules = [[]]
|
288
|
-
|
289
|
-
while scanner.rest?
|
290
|
-
rules.last << scanner.scan(/[^",&]*/)
|
291
|
-
case scanner.scan(/./)
|
292
|
-
when '&'; rules.last << :parent
|
293
|
-
when ','
|
294
|
-
scanner.scan(/\s*/)
|
295
|
-
if scanner.rest?
|
296
|
-
rules << []
|
297
|
-
rules.last << "\n" if scanner.matched.include?("\n")
|
298
|
-
end
|
299
|
-
when '"'
|
300
|
-
rules.last << '"' << scanner.scan(/([^"\\]|\\.)*/)
|
301
|
-
# We don't want to enforce that strings are closed,
|
302
|
-
# but we do want to consume quotes or trailing backslashes.
|
303
|
-
rules.last << scanner.scan(/./) if scanner.rest?
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
rules.map! do |l|
|
308
|
-
Haml::Util.merge_adjacent_strings(l).reject {|r| r.is_a?(String) && r.empty?}
|
309
|
-
end
|
310
|
-
|
311
|
-
rules
|
312
|
-
end
|
313
|
-
|
314
258
|
def debug_info_rule
|
315
259
|
node = DirectiveNode.new("@media -sass-debug-info")
|
316
260
|
debug_info.map {|k, v| [k.to_s, v.to_s]}.sort.each do |k, v|
|
317
261
|
rule = RuleNode.new([""])
|
318
|
-
rule.resolved_rules =
|
262
|
+
rule.resolved_rules = Sass::Selector::CommaSequence.new(
|
263
|
+
[Sass::Selector::Sequence.new(
|
264
|
+
[Sass::Selector::SimpleSequence.new(
|
265
|
+
[Sass::Selector::Element.new(k.to_s.gsub(/[^\w-]/, "\\\\\\0"), nil)])
|
266
|
+
])
|
267
|
+
])
|
319
268
|
prop = PropNode.new([""], "", :new)
|
320
269
|
prop.resolved_name = "font-family"
|
321
270
|
prop.resolved_value = Sass::SCSS::RX.escape_ident(v.to_s)
|
data/lib/sass/tree/warn_node.rb
CHANGED
data/lib/sass/tree/while_node.rb
CHANGED
data/lib/sass.rb
CHANGED
data/test/haml/engine_test.rb
CHANGED
@@ -1348,17 +1348,199 @@ SASS
|
|
1348
1348
|
render("%a{:a => 'b',\n:b => 'c'}(c='d'\nd='e') bar"))
|
1349
1349
|
end
|
1350
1350
|
|
1351
|
+
# Ruby Multiline
|
1352
|
+
|
1353
|
+
def test_silent_ruby_multiline
|
1354
|
+
assert_equal(<<HTML, render(<<HAML))
|
1355
|
+
bar, baz, bang
|
1356
|
+
<p>foo</p>
|
1357
|
+
HTML
|
1358
|
+
- foo = ["bar",
|
1359
|
+
"baz",
|
1360
|
+
"bang"]
|
1361
|
+
= foo.join(", ")
|
1362
|
+
%p foo
|
1363
|
+
HAML
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
def test_loud_ruby_multiline
|
1367
|
+
assert_equal(<<HTML, render(<<HAML))
|
1368
|
+
bar, baz, bang
|
1369
|
+
<p>foo</p>
|
1370
|
+
<p>bar</p>
|
1371
|
+
HTML
|
1372
|
+
= ["bar",
|
1373
|
+
"baz",
|
1374
|
+
"bang"].join(", ")
|
1375
|
+
%p foo
|
1376
|
+
%p bar
|
1377
|
+
HAML
|
1378
|
+
end
|
1379
|
+
|
1380
|
+
def test_escaped_loud_ruby_multiline
|
1381
|
+
assert_equal(<<HTML, render(<<HAML))
|
1382
|
+
bar<, baz, bang
|
1383
|
+
<p>foo</p>
|
1384
|
+
<p>bar</p>
|
1385
|
+
HTML
|
1386
|
+
&= ["bar<",
|
1387
|
+
"baz",
|
1388
|
+
"bang"].join(", ")
|
1389
|
+
%p foo
|
1390
|
+
%p bar
|
1391
|
+
HAML
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
def test_unescaped_loud_ruby_multiline
|
1395
|
+
assert_equal(<<HTML, render(<<HAML, :escape_html => true))
|
1396
|
+
bar<, baz, bang
|
1397
|
+
<p>foo</p>
|
1398
|
+
<p>bar</p>
|
1399
|
+
HTML
|
1400
|
+
!= ["bar<",
|
1401
|
+
"baz",
|
1402
|
+
"bang"].join(", ")
|
1403
|
+
%p foo
|
1404
|
+
%p bar
|
1405
|
+
HAML
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
def test_flattened_loud_ruby_multiline
|
1409
|
+
assert_equal(<<HTML, render(<<HAML))
|
1410
|
+
<pre>bar
baz
bang</pre>
|
1411
|
+
<p>foo</p>
|
1412
|
+
<p>bar</p>
|
1413
|
+
HTML
|
1414
|
+
~ "<pre>" + ["bar",
|
1415
|
+
"baz",
|
1416
|
+
"bang"].join("\\n") + "</pre>"
|
1417
|
+
%p foo
|
1418
|
+
%p bar
|
1419
|
+
HAML
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
def test_loud_ruby_multiline_with_block
|
1423
|
+
assert_equal(<<HTML, render(<<HAML))
|
1424
|
+
farfazfang
|
1425
|
+
<p>foo</p>
|
1426
|
+
<p>bar</p>
|
1427
|
+
HTML
|
1428
|
+
= ["bar",
|
1429
|
+
"baz",
|
1430
|
+
"bang"].map do |str|
|
1431
|
+
- str.gsub("ba",
|
1432
|
+
"fa")
|
1433
|
+
%p foo
|
1434
|
+
%p bar
|
1435
|
+
HAML
|
1436
|
+
end
|
1437
|
+
|
1438
|
+
def test_silent_ruby_multiline_with_block
|
1439
|
+
assert_equal(<<HTML, render(<<HAML))
|
1440
|
+
far
|
1441
|
+
faz
|
1442
|
+
fang
|
1443
|
+
<p>foo</p>
|
1444
|
+
<p>bar</p>
|
1445
|
+
HTML
|
1446
|
+
- ["bar",
|
1447
|
+
"baz",
|
1448
|
+
"bang"].map do |str|
|
1449
|
+
= str.gsub("ba",
|
1450
|
+
"fa")
|
1451
|
+
%p foo
|
1452
|
+
%p bar
|
1453
|
+
HAML
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
def test_ruby_multiline_in_tag
|
1457
|
+
assert_equal(<<HTML, render(<<HAML))
|
1458
|
+
<p>foo, bar, baz</p>
|
1459
|
+
<p>foo</p>
|
1460
|
+
<p>bar</p>
|
1461
|
+
HTML
|
1462
|
+
%p= ["foo",
|
1463
|
+
"bar",
|
1464
|
+
"baz"].join(", ")
|
1465
|
+
%p foo
|
1466
|
+
%p bar
|
1467
|
+
HAML
|
1468
|
+
end
|
1469
|
+
|
1470
|
+
def test_escaped_ruby_multiline_in_tag
|
1471
|
+
assert_equal(<<HTML, render(<<HAML))
|
1472
|
+
<p>foo<, bar, baz</p>
|
1473
|
+
<p>foo</p>
|
1474
|
+
<p>bar</p>
|
1475
|
+
HTML
|
1476
|
+
%p&= ["foo<",
|
1477
|
+
"bar",
|
1478
|
+
"baz"].join(", ")
|
1479
|
+
%p foo
|
1480
|
+
%p bar
|
1481
|
+
HAML
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
def test_unescaped_ruby_multiline_in_tag
|
1485
|
+
assert_equal(<<HTML, render(<<HAML, :escape_html => true))
|
1486
|
+
<p>foo<, bar, baz</p>
|
1487
|
+
<p>foo</p>
|
1488
|
+
<p>bar</p>
|
1489
|
+
HTML
|
1490
|
+
%p!= ["foo<",
|
1491
|
+
"bar",
|
1492
|
+
"baz"].join(", ")
|
1493
|
+
%p foo
|
1494
|
+
%p bar
|
1495
|
+
HAML
|
1496
|
+
end
|
1497
|
+
|
1498
|
+
def test_ruby_multiline_with_normal_multiline
|
1499
|
+
assert_equal(<<HTML, render(<<HAML))
|
1500
|
+
foobarbar, baz, bang
|
1501
|
+
<p>foo</p>
|
1502
|
+
<p>bar</p>
|
1503
|
+
HTML
|
1504
|
+
= "foo" + |
|
1505
|
+
"bar" + |
|
1506
|
+
["bar", |
|
1507
|
+
"baz",
|
1508
|
+
"bang"].join(", ")
|
1509
|
+
%p foo
|
1510
|
+
%p bar
|
1511
|
+
HAML
|
1512
|
+
end
|
1513
|
+
|
1514
|
+
def test_ruby_multiline_after_filter
|
1515
|
+
assert_equal(<<HTML, render(<<HAML))
|
1516
|
+
foo
|
1517
|
+
bar
|
1518
|
+
bar, baz, bang
|
1519
|
+
<p>foo</p>
|
1520
|
+
<p>bar</p>
|
1521
|
+
HTML
|
1522
|
+
:plain
|
1523
|
+
foo
|
1524
|
+
bar
|
1525
|
+
= ["bar",
|
1526
|
+
"baz",
|
1527
|
+
"bang"].join(", ")
|
1528
|
+
%p foo
|
1529
|
+
%p bar
|
1530
|
+
HAML
|
1531
|
+
end
|
1532
|
+
|
1351
1533
|
# Encodings
|
1352
1534
|
|
1353
1535
|
def test_utf_8_bom
|
1354
|
-
assert_equal <<
|
1536
|
+
assert_equal <<HTML, render(<<HAML)
|
1355
1537
|
<div class='foo'>
|
1356
1538
|
<p>baz</p>
|
1357
1539
|
</div>
|
1358
|
-
|
1540
|
+
HTML
|
1359
1541
|
\xEF\xBB\xBF.foo
|
1360
1542
|
%p baz
|
1361
|
-
|
1543
|
+
HAML
|
1362
1544
|
end
|
1363
1545
|
|
1364
1546
|
unless Haml::Util.ruby1_8?
|
data/test/haml/helper_test.rb
CHANGED
@@ -15,7 +15,18 @@ module Haml::Helpers
|
|
15
15
|
end
|
16
16
|
|
17
17
|
class HelperTest < Test::Unit::TestCase
|
18
|
-
Post = Struct.new('Post', :body)
|
18
|
+
Post = Struct.new('Post', :body, :error_field, :errors)
|
19
|
+
class PostErrors
|
20
|
+
def on(name)
|
21
|
+
return unless name == 'error_field'
|
22
|
+
["Really bad error"]
|
23
|
+
end
|
24
|
+
alias_method :full_messages, :on
|
25
|
+
|
26
|
+
def [](name)
|
27
|
+
on(name) || []
|
28
|
+
end
|
29
|
+
end
|
19
30
|
|
20
31
|
def setup
|
21
32
|
@base = ActionView::Base.new
|
@@ -26,7 +37,7 @@ class HelperTest < Test::Unit::TestCase
|
|
26
37
|
@base.controller.response = ActionController::Response.new
|
27
38
|
end
|
28
39
|
|
29
|
-
@base.instance_variable_set('@post', Post.new("Foo bar\nbaz"))
|
40
|
+
@base.instance_variable_set('@post', Post.new("Foo bar\nbaz", nil, PostErrors.new))
|
30
41
|
end
|
31
42
|
|
32
43
|
def render(text, options = {})
|
@@ -153,6 +164,18 @@ HTML
|
|
153
164
|
HAML
|
154
165
|
end
|
155
166
|
|
167
|
+
def test_content_tag_error_wrapping
|
168
|
+
def @base.protect_against_forgery?; false; end
|
169
|
+
assert_equal(<<HTML, render(<<HAML, :action_view))
|
170
|
+
<form action="" method="post">
|
171
|
+
<div class="fieldWithErrors"><label for="post_error_field">Error field</label></div>
|
172
|
+
</form>
|
173
|
+
HTML
|
174
|
+
#{rails_block_helper_char} form_for #{form_for_calling_convention('post')}, :url => '' do |f|
|
175
|
+
= f.label 'error_field'
|
176
|
+
HAML
|
177
|
+
end
|
178
|
+
|
156
179
|
def test_haml_tag_name_attribute_with_id
|
157
180
|
assert_equal("<p id='some_id'></p>\n", render("- haml_tag 'p#some_id'"))
|
158
181
|
end
|
data/test/haml/template_test.rb
CHANGED
@@ -288,7 +288,7 @@ END
|
|
288
288
|
<input id="article_body" name="article[body]" size="30" type="text" value="World" />
|
289
289
|
</form>
|
290
290
|
HTML
|
291
|
-
- form_for :article,
|
291
|
+
- form_for #{form_for_calling_convention(:article)}, :url => '' do |f|
|
292
292
|
Title:
|
293
293
|
= f.text_field :title
|
294
294
|
Body:
|
@@ -387,7 +387,7 @@ HAML
|
|
387
387
|
<input id="article_body" name="article[body]" size="30" type="text" value="World" />
|
388
388
|
</form>
|
389
389
|
HTML
|
390
|
-
#{rails_block_helper_char} form_for :article,
|
390
|
+
#{rails_block_helper_char} form_for #{form_for_calling_convention(:article)}, :url => '' do |f|
|
391
391
|
Title:
|
392
392
|
= f.text_field :title
|
393
393
|
Body:
|
@@ -62,6 +62,19 @@ click
|
|
62
62
|
<input id="article_body" name="article[body]" size="30" type="text" value="World" />
|
63
63
|
</form>
|
64
64
|
</div>
|
65
|
+
- elsif Haml::Util.ap_geq_3_beta_3?
|
66
|
+
%p
|
67
|
+
= form_tag ''
|
68
|
+
%div
|
69
|
+
= form_tag '' do
|
70
|
+
%div= submit_tag 'save'
|
71
|
+
- @foo = 'value one'
|
72
|
+
= test_partial 'partial'
|
73
|
+
= form_for @article, :as => :article, :url => '', :html => {:class => nil, :id => nil} do |f|
|
74
|
+
Title:
|
75
|
+
= f.text_field :title
|
76
|
+
Body:
|
77
|
+
= f.text_field :body
|
65
78
|
- elsif Haml::Util.ap_geq_3?
|
66
79
|
%p
|
67
80
|
= form_tag ''
|