haml 4.0.0 → 5.0.0
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.
- checksums.yaml +7 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +117 -5
- data/FAQ.md +7 -17
- data/MIT-LICENSE +1 -1
- data/README.md +85 -42
- data/REFERENCE.md +181 -86
- data/Rakefile +47 -51
- data/lib/haml/attribute_builder.rb +163 -0
- data/lib/haml/attribute_compiler.rb +215 -0
- data/lib/haml/attribute_parser.rb +144 -0
- data/lib/haml/buffer.rb +38 -128
- data/lib/haml/compiler.rb +88 -295
- data/lib/haml/engine.rb +25 -41
- data/lib/haml/error.rb +3 -0
- data/lib/haml/escapable.rb +49 -0
- data/lib/haml/exec.rb +33 -19
- data/lib/haml/filters.rb +20 -24
- data/lib/haml/generator.rb +41 -0
- data/lib/haml/helpers/action_view_extensions.rb +3 -2
- data/lib/haml/helpers/action_view_mods.rb +44 -66
- data/lib/haml/helpers/action_view_xss_mods.rb +1 -0
- data/lib/haml/helpers/safe_erubi_template.rb +27 -0
- data/lib/haml/helpers/safe_erubis_template.rb +16 -4
- data/lib/haml/helpers/xss_mods.rb +18 -12
- data/lib/haml/helpers.rb +122 -58
- data/lib/haml/options.rb +39 -46
- data/lib/haml/parser.rb +278 -217
- data/lib/haml/{template/plugin.rb → plugin.rb} +8 -15
- data/lib/haml/railtie.rb +21 -11
- data/lib/haml/sass_rails_filter.rb +17 -4
- data/lib/haml/template/options.rb +12 -2
- data/lib/haml/template.rb +12 -6
- data/lib/haml/temple_engine.rb +120 -0
- data/lib/haml/temple_line_counter.rb +29 -0
- data/lib/haml/util.rb +80 -199
- data/lib/haml/version.rb +2 -1
- data/lib/haml.rb +2 -1
- data/test/attribute_parser_test.rb +101 -0
- data/test/engine_test.rb +306 -176
- data/test/filters_test.rb +32 -19
- data/test/gemfiles/Gemfile.rails-4.0.x +11 -0
- data/test/gemfiles/Gemfile.rails-4.0.x.lock +87 -0
- data/test/gemfiles/Gemfile.rails-4.1.x +5 -0
- data/test/gemfiles/Gemfile.rails-4.2.x +5 -0
- data/test/gemfiles/Gemfile.rails-5.0.x +4 -0
- data/test/helper_test.rb +282 -96
- data/test/options_test.rb +22 -0
- data/test/parser_test.rb +71 -4
- data/test/results/bemit.xhtml +4 -0
- data/test/results/eval_suppressed.xhtml +4 -4
- data/test/results/helpers.xhtml +43 -41
- data/test/results/helpful.xhtml +6 -3
- data/test/results/just_stuff.xhtml +21 -20
- data/test/results/list.xhtml +9 -9
- data/test/results/nuke_inner_whitespace.xhtml +22 -22
- data/test/results/nuke_outer_whitespace.xhtml +84 -92
- data/test/results/original_engine.xhtml +17 -17
- data/test/results/partial_layout.xhtml +4 -3
- data/test/results/partial_layout_erb.xhtml +4 -3
- data/test/results/partials.xhtml +11 -10
- data/test/results/silent_script.xhtml +63 -63
- data/test/results/standard.xhtml +156 -159
- data/test/results/tag_parsing.xhtml +19 -19
- data/test/results/very_basic.xhtml +2 -2
- data/test/results/whitespace_handling.xhtml +56 -50
- data/test/template_test.rb +44 -53
- data/test/template_test_helper.rb +38 -0
- data/test/templates/_text_area_helper.html.haml +4 -0
- data/test/templates/bemit.haml +3 -0
- data/test/templates/just_stuff.haml +1 -0
- data/test/templates/partial_layout_erb.erb +1 -1
- data/test/templates/standard_ugly.haml +1 -0
- data/test/templates/with_bom.haml +1 -0
- data/test/temple_line_counter_test.rb +40 -0
- data/test/test_helper.rb +26 -12
- data/test/util_test.rb +6 -47
- metadata +88 -106
- data/lib/haml/helpers/rails_323_textarea_fix.rb +0 -24
- data/test/gemfiles/Gemfile.rails-3.0.x +0 -5
- data/test/gemfiles/Gemfile.rails-3.1.x +0 -6
- data/test/gemfiles/Gemfile.rails-3.2.x +0 -5
- data/test/gemfiles/Gemfile.rails-master +0 -4
- data/test/templates/_av_partial_1_ugly.haml +0 -9
- data/test/templates/_av_partial_2_ugly.haml +0 -5
- data/test/templates/action_view_ugly.haml +0 -47
- data/test/templates/standard_ugly.haml +0 -43
data/lib/haml/buffer.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Haml
|
2
3
|
# This class is used only internally. It holds the buffer of HTML that
|
3
4
|
# is eventually output as the resulting document.
|
@@ -90,15 +91,14 @@ module Haml
|
|
90
91
|
def initialize(upper = nil, options = {})
|
91
92
|
@active = true
|
92
93
|
@upper = upper
|
93
|
-
@options =
|
94
|
+
@options = Options.buffer_defaults
|
95
|
+
@options = @options.merge(options) unless options.empty?
|
94
96
|
@buffer = new_encoded_string
|
95
97
|
@tabulation = 0
|
96
98
|
|
97
99
|
# The number of tabs that Engine thinks we should have
|
98
100
|
# @real_tabs + @tabulation is the number of tabs actually output
|
99
101
|
@real_tabs = 0
|
100
|
-
|
101
|
-
@preserve_pattern = /<[\s]*#{@options[:preserve].join("|")}/i
|
102
102
|
end
|
103
103
|
|
104
104
|
# Appends text to the buffer, properly tabulated.
|
@@ -117,8 +117,8 @@ module Haml
|
|
117
117
|
text.sub!(tabs, '') if dont_tab_up
|
118
118
|
end
|
119
119
|
|
120
|
-
@buffer << text
|
121
120
|
@real_tabs += tab_change
|
121
|
+
@buffer << text
|
122
122
|
end
|
123
123
|
|
124
124
|
# Modifies the indentation of the document.
|
@@ -129,82 +129,13 @@ module Haml
|
|
129
129
|
@real_tabs += tab_change
|
130
130
|
end
|
131
131
|
|
132
|
-
Haml::Util.def_static_method(self, :format_script, [:result],
|
133
|
-
:preserve_script, :in_tag, :preserve_tag, :escape_html,
|
134
|
-
:nuke_inner_whitespace, :interpolated, :ugly, <<RUBY)
|
135
|
-
<% # Escape HTML here so that the safety of the string is preserved in Rails
|
136
|
-
result_name = escape_html ? "html_escape(result.to_s)" : "result.to_s" %>
|
137
|
-
<% unless ugly %>
|
138
|
-
# If we're interpolated,
|
139
|
-
# then the custom tabulation is handled in #push_text.
|
140
|
-
# The easiest way to avoid it here is to reset @tabulation.
|
141
|
-
<% if interpolated %>
|
142
|
-
old_tabulation = @tabulation
|
143
|
-
@tabulation = 0
|
144
|
-
<% end %>
|
145
|
-
|
146
|
-
<% if !(in_tag && preserve_tag && !nuke_inner_whitespace) %>
|
147
|
-
tabulation = @real_tabs
|
148
|
-
<% end %>
|
149
|
-
result = <%= result_name %>.<% if nuke_inner_whitespace %>strip<% else %>rstrip<% end %>
|
150
|
-
<% else %>
|
151
|
-
result = <%= result_name %><% if nuke_inner_whitespace %>.strip<% end %>
|
152
|
-
<% end %>
|
153
|
-
|
154
|
-
<% if preserve_tag %>
|
155
|
-
result = Haml::Helpers.preserve(result)
|
156
|
-
<% elsif preserve_script %>
|
157
|
-
result = Haml::Helpers.find_and_preserve(result, options[:preserve])
|
158
|
-
<% end %>
|
159
|
-
|
160
|
-
<% if ugly %>
|
161
|
-
return result
|
162
|
-
<% else %>
|
163
|
-
|
164
|
-
return result if self.instance_variable_get(:@preserve_pattern).match(result)
|
165
|
-
|
166
|
-
<% if !(in_tag && preserve_tag && !nuke_inner_whitespace) %>
|
167
|
-
has_newline = result.include?("\\n")
|
168
|
-
<% end %>
|
169
|
-
|
170
|
-
<% if in_tag && !nuke_inner_whitespace %>
|
171
|
-
<% unless preserve_tag %> if !has_newline <% end %>
|
172
|
-
@real_tabs -= 1
|
173
|
-
<% if interpolated %> @tabulation = old_tabulation <% end %>
|
174
|
-
return result
|
175
|
-
<% unless preserve_tag %> end <% end %>
|
176
|
-
<% end %>
|
177
|
-
|
178
|
-
<% if !(in_tag && preserve_tag && !nuke_inner_whitespace) %>
|
179
|
-
# Precompiled tabulation may be wrong
|
180
|
-
<% if !interpolated && !in_tag %>
|
181
|
-
result = tabs + result if @tabulation > 0
|
182
|
-
<% end %>
|
183
|
-
|
184
|
-
if has_newline
|
185
|
-
result = result.gsub "\\n", "\\n" + tabs(tabulation)
|
186
|
-
|
187
|
-
# Add tabulation if it wasn't precompiled
|
188
|
-
<% if in_tag && !nuke_inner_whitespace %> result = tabs(tabulation) + result <% end %>
|
189
|
-
end
|
190
|
-
|
191
|
-
<% if in_tag && !nuke_inner_whitespace %>
|
192
|
-
result = "\\n\#{result}\\n\#{tabs(tabulation-1)}"
|
193
|
-
@real_tabs -= 1
|
194
|
-
<% end %>
|
195
|
-
<% if interpolated %> @tabulation = old_tabulation <% end %>
|
196
|
-
result
|
197
|
-
<% end %>
|
198
|
-
<% end %>
|
199
|
-
RUBY
|
200
|
-
|
201
132
|
def attributes(class_id, obj_ref, *attributes_hashes)
|
202
133
|
attributes = class_id
|
203
134
|
attributes_hashes.each do |old|
|
204
|
-
|
135
|
+
AttributeBuilder.merge_attributes!(attributes, Hash[old.map {|k, v| [k.to_s, v]}])
|
205
136
|
end
|
206
|
-
|
207
|
-
|
137
|
+
AttributeBuilder.merge_attributes!(attributes, parse_object_ref(obj_ref)) if obj_ref
|
138
|
+
AttributeBuilder.build_attributes(
|
208
139
|
html?, @options[:attr_wrapper], @options[:escape_attrs], @options[:hyphenate_data_attrs], attributes)
|
209
140
|
end
|
210
141
|
|
@@ -219,58 +150,35 @@ RUBY
|
|
219
150
|
buffer << buffer.slice!(capture_position..-1).rstrip
|
220
151
|
end
|
221
152
|
|
222
|
-
#
|
223
|
-
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
# ids are concatenated with `"_"`,
|
227
|
-
# and classes are concatenated with `" "`.
|
228
|
-
# data hashes are simply merged.
|
153
|
+
# Works like #{find_and_preserve}, but allows the first newline after a
|
154
|
+
# preserved opening tag to remain unencoded, and then outdents the content.
|
155
|
+
# This change was motivated primarily by the change in Rails 3.2.3 to emit
|
156
|
+
# a newline after textarea helpers.
|
229
157
|
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
# @
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
#
|
246
|
-
from['class'] = (from['class'].to_s.split(' ') | to['class'].split(' ')).sort.join(' ')
|
247
|
-
elsif to['class'] || from['class']
|
248
|
-
from['class'] ||= to['class']
|
158
|
+
# @param input [String] The text to process
|
159
|
+
# @since Haml 4.0.1
|
160
|
+
# @private
|
161
|
+
def fix_textareas!(input)
|
162
|
+
return input unless toplevel? && input.include?('<textarea'.freeze)
|
163
|
+
|
164
|
+
pattern = /<(textarea)([^>]*)>(\n|
)(.*?)<\/textarea>/im
|
165
|
+
input.gsub!(pattern) do |s|
|
166
|
+
match = pattern.match(s)
|
167
|
+
content = match[4]
|
168
|
+
if match[3] == '
'
|
169
|
+
content.sub!(/\A /, ' ')
|
170
|
+
else
|
171
|
+
content.sub!(/\A[ ]*/, '')
|
172
|
+
end
|
173
|
+
"<#{match[1]}#{match[2]}>\n#{content}</#{match[1]}>"
|
249
174
|
end
|
250
|
-
|
251
|
-
from_data = from.delete('data') || {}
|
252
|
-
to_data = to.delete('data') || {}
|
253
|
-
|
254
|
-
# forces to_data & from_data into a hash
|
255
|
-
from_data = { nil => from_data } unless from_data.is_a?(Hash)
|
256
|
-
to_data = { nil => to_data } unless to_data.is_a?(Hash)
|
257
|
-
|
258
|
-
merged_data = to_data.merge(from_data)
|
259
|
-
|
260
|
-
to['data'] = merged_data unless merged_data.empty?
|
261
|
-
to.merge!(from)
|
175
|
+
input
|
262
176
|
end
|
263
177
|
|
264
178
|
private
|
265
179
|
|
266
|
-
|
267
|
-
|
268
|
-
""
|
269
|
-
end
|
270
|
-
else
|
271
|
-
def new_encoded_string
|
272
|
-
"".encode(Encoding.find(options[:encoding]))
|
273
|
-
end
|
180
|
+
def new_encoded_string
|
181
|
+
"".encode(options[:encoding])
|
274
182
|
end
|
275
183
|
|
276
184
|
@@tab_cache = {}
|
@@ -308,18 +216,20 @@ RUBY
|
|
308
216
|
id = "#{ prefix }_#{ id }"
|
309
217
|
end
|
310
218
|
|
311
|
-
{'id' => id, 'class' => class_name}
|
219
|
+
{ 'id'.freeze => id, 'class'.freeze => class_name }
|
312
220
|
end
|
313
221
|
|
314
222
|
# Changes a word from camel case to underscores.
|
315
223
|
# Based on the method of the same name in Rails' Inflector,
|
316
224
|
# but copied here so it'll run properly without Rails.
|
317
225
|
def underscore(camel_cased_word)
|
318
|
-
camel_cased_word.to_s.
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
226
|
+
word = camel_cased_word.to_s.dup
|
227
|
+
word.gsub!(/::/, '_')
|
228
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
229
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
230
|
+
word.tr!('-', '_')
|
231
|
+
word.downcase!
|
232
|
+
word
|
323
233
|
end
|
324
234
|
end
|
325
235
|
end
|