haml-edge 2.3.209 → 2.3.210
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 ''
|