haml 4.0.7 → 5.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +18 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +54 -0
  5. data/.yardopts +1 -1
  6. data/CHANGELOG.md +96 -4
  7. data/FAQ.md +4 -14
  8. data/Gemfile +19 -0
  9. data/MIT-LICENSE +1 -1
  10. data/README.md +80 -42
  11. data/REFERENCE.md +116 -64
  12. data/Rakefile +46 -54
  13. data/TODO +24 -0
  14. data/benchmark.rb +66 -0
  15. data/haml.gemspec +38 -0
  16. data/lib/haml/.gitattributes +1 -0
  17. data/lib/haml/attribute_builder.rb +163 -0
  18. data/lib/haml/attribute_compiler.rb +223 -0
  19. data/lib/haml/attribute_parser.rb +148 -0
  20. data/lib/haml/buffer.rb +22 -132
  21. data/lib/haml/compiler.rb +89 -298
  22. data/lib/haml/engine.rb +25 -41
  23. data/lib/haml/error.rb +3 -0
  24. data/lib/haml/escapable.rb +49 -0
  25. data/lib/haml/exec.rb +38 -19
  26. data/lib/haml/filters.rb +18 -24
  27. data/lib/haml/generator.rb +41 -0
  28. data/lib/haml/helpers/action_view_extensions.rb +3 -2
  29. data/lib/haml/helpers/action_view_mods.rb +42 -60
  30. data/lib/haml/helpers/action_view_xss_mods.rb +1 -0
  31. data/lib/haml/helpers/safe_erubi_template.rb +19 -0
  32. data/lib/haml/helpers/safe_erubis_template.rb +4 -1
  33. data/lib/haml/helpers/xss_mods.rb +18 -12
  34. data/lib/haml/helpers.rb +132 -89
  35. data/lib/haml/options.rb +41 -47
  36. data/lib/haml/parser.rb +278 -216
  37. data/lib/haml/{template/plugin.rb → plugin.rb} +8 -15
  38. data/lib/haml/railtie.rb +38 -12
  39. data/lib/haml/sass_rails_filter.rb +17 -4
  40. data/lib/haml/template/options.rb +12 -2
  41. data/lib/haml/template.rb +12 -6
  42. data/lib/haml/temple_engine.rb +121 -0
  43. data/lib/haml/temple_line_counter.rb +29 -0
  44. data/lib/haml/util.rb +80 -199
  45. data/lib/haml/version.rb +2 -1
  46. data/lib/haml.rb +1 -0
  47. data/yard/default/.gitignore +1 -0
  48. data/yard/default/fulldoc/html/css/common.sass +15 -0
  49. data/yard/default/layout/html/footer.erb +12 -0
  50. metadata +50 -111
  51. data/test/engine_test.rb +0 -2013
  52. data/test/erb/_av_partial_1.erb +0 -12
  53. data/test/erb/_av_partial_2.erb +0 -8
  54. data/test/erb/action_view.erb +0 -62
  55. data/test/erb/standard.erb +0 -55
  56. data/test/filters_test.rb +0 -254
  57. data/test/gemfiles/Gemfile.rails-3.0.x +0 -5
  58. data/test/gemfiles/Gemfile.rails-3.1.x +0 -6
  59. data/test/gemfiles/Gemfile.rails-3.2.x +0 -5
  60. data/test/gemfiles/Gemfile.rails-4.0.x +0 -5
  61. data/test/haml-spec/LICENSE +0 -14
  62. data/test/haml-spec/README.md +0 -106
  63. data/test/haml-spec/lua_haml_spec.lua +0 -38
  64. data/test/haml-spec/perl_haml_test.pl +0 -81
  65. data/test/haml-spec/ruby_haml_test.rb +0 -23
  66. data/test/haml-spec/tests.json +0 -660
  67. data/test/helper_test.rb +0 -583
  68. data/test/markaby/standard.mab +0 -52
  69. data/test/mocks/article.rb +0 -6
  70. data/test/parser_test.rb +0 -105
  71. data/test/results/content_for_layout.xhtml +0 -12
  72. data/test/results/eval_suppressed.xhtml +0 -9
  73. data/test/results/helpers.xhtml +0 -70
  74. data/test/results/helpful.xhtml +0 -10
  75. data/test/results/just_stuff.xhtml +0 -70
  76. data/test/results/list.xhtml +0 -12
  77. data/test/results/nuke_inner_whitespace.xhtml +0 -40
  78. data/test/results/nuke_outer_whitespace.xhtml +0 -148
  79. data/test/results/original_engine.xhtml +0 -20
  80. data/test/results/partial_layout.xhtml +0 -5
  81. data/test/results/partial_layout_erb.xhtml +0 -5
  82. data/test/results/partials.xhtml +0 -21
  83. data/test/results/render_layout.xhtml +0 -3
  84. data/test/results/silent_script.xhtml +0 -74
  85. data/test/results/standard.xhtml +0 -162
  86. data/test/results/tag_parsing.xhtml +0 -23
  87. data/test/results/very_basic.xhtml +0 -5
  88. data/test/results/whitespace_handling.xhtml +0 -90
  89. data/test/template_test.rb +0 -354
  90. data/test/templates/_av_partial_1.haml +0 -9
  91. data/test/templates/_av_partial_1_ugly.haml +0 -9
  92. data/test/templates/_av_partial_2.haml +0 -5
  93. data/test/templates/_av_partial_2_ugly.haml +0 -5
  94. data/test/templates/_layout.erb +0 -3
  95. data/test/templates/_layout_for_partial.haml +0 -3
  96. data/test/templates/_partial.haml +0 -8
  97. data/test/templates/_text_area.haml +0 -3
  98. data/test/templates/_text_area_helper.html.haml +0 -4
  99. data/test/templates/action_view.haml +0 -47
  100. data/test/templates/action_view_ugly.haml +0 -47
  101. data/test/templates/breakage.haml +0 -8
  102. data/test/templates/content_for_layout.haml +0 -8
  103. data/test/templates/eval_suppressed.haml +0 -11
  104. data/test/templates/helpers.haml +0 -55
  105. data/test/templates/helpful.haml +0 -11
  106. data/test/templates/just_stuff.haml +0 -85
  107. data/test/templates/list.haml +0 -12
  108. data/test/templates/nuke_inner_whitespace.haml +0 -32
  109. data/test/templates/nuke_outer_whitespace.haml +0 -144
  110. data/test/templates/original_engine.haml +0 -17
  111. data/test/templates/partial_layout.haml +0 -3
  112. data/test/templates/partial_layout_erb.erb +0 -4
  113. data/test/templates/partialize.haml +0 -1
  114. data/test/templates/partials.haml +0 -12
  115. data/test/templates/render_layout.haml +0 -2
  116. data/test/templates/silent_script.haml +0 -45
  117. data/test/templates/standard.haml +0 -43
  118. data/test/templates/standard_ugly.haml +0 -43
  119. data/test/templates/tag_parsing.haml +0 -21
  120. data/test/templates/very_basic.haml +0 -4
  121. data/test/templates/whitespace_handling.haml +0 -87
  122. data/test/test_helper.rb +0 -81
  123. data/test/util_test.rb +0 -63
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,7 +91,8 @@ module Haml
90
91
  def initialize(upper = nil, options = {})
91
92
  @active = true
92
93
  @upper = upper
93
- @options = 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
 
@@ -115,8 +117,8 @@ module Haml
115
117
  text.sub!(tabs, '') if dont_tab_up
116
118
  end
117
119
 
118
- @buffer << text
119
120
  @real_tabs += tab_change
121
+ @buffer << text
120
122
  end
121
123
 
122
124
  # Modifies the indentation of the document.
@@ -127,82 +129,13 @@ module Haml
127
129
  @real_tabs += tab_change
128
130
  end
129
131
 
130
- Haml::Util.def_static_method(self, :format_script, [:result],
131
- :preserve_script, :in_tag, :preserve_tag, :escape_html,
132
- :nuke_inner_whitespace, :interpolated, :ugly, <<RUBY)
133
- <% # Escape HTML here so that the safety of the string is preserved in Rails
134
- result_name = escape_html ? "html_escape(result.to_s)" : "result.to_s" %>
135
- <% unless ugly %>
136
- # If we're interpolated,
137
- # then the custom tabulation is handled in #push_text.
138
- # The easiest way to avoid it here is to reset @tabulation.
139
- <% if interpolated %>
140
- old_tabulation = @tabulation
141
- @tabulation = 0
142
- <% end %>
143
-
144
- <% if !(in_tag && preserve_tag && !nuke_inner_whitespace) %>
145
- tabulation = @real_tabs
146
- <% end %>
147
- result = <%= result_name %>.<% if nuke_inner_whitespace %>strip<% else %>rstrip<% end %>
148
- <% else %>
149
- result = <%= result_name %><% if nuke_inner_whitespace %>.strip<% end %>
150
- <% end %>
151
-
152
- <% if preserve_tag %>
153
- result = Haml::Helpers.preserve(result)
154
- <% elsif preserve_script %>
155
- result = Haml::Helpers.find_and_preserve(result, options[:preserve])
156
- <% end %>
157
-
158
- <% if ugly %>
159
- fix_textareas!(result) if toplevel? && result.include?('<textarea')
160
- return result
161
- <% else %>
162
- <% if !(in_tag && preserve_tag && !nuke_inner_whitespace) %>
163
- has_newline = result.include?("\\n")
164
- <% end %>
165
-
166
- <% if in_tag && !nuke_inner_whitespace %>
167
- <% unless preserve_tag %> if !has_newline <% end %>
168
- @real_tabs -= 1
169
- <% if interpolated %> @tabulation = old_tabulation <% end %>
170
- return result
171
- <% unless preserve_tag %> end <% end %>
172
- <% end %>
173
-
174
- <% if !(in_tag && preserve_tag && !nuke_inner_whitespace) %>
175
- # Precompiled tabulation may be wrong
176
- <% if !interpolated && !in_tag %>
177
- result = tabs + result if @tabulation > 0
178
- <% end %>
179
-
180
- if has_newline
181
- result = result.gsub "\\n", "\\n" + tabs(tabulation)
182
-
183
- # Add tabulation if it wasn't precompiled
184
- <% if in_tag && !nuke_inner_whitespace %> result = tabs(tabulation) + result <% end %>
185
- end
186
-
187
- fix_textareas!(result) if toplevel? && result.include?('<textarea')
188
-
189
- <% if in_tag && !nuke_inner_whitespace %>
190
- result = "\\n\#{result}\\n\#{tabs(tabulation-1)}"
191
- @real_tabs -= 1
192
- <% end %>
193
- <% if interpolated %> @tabulation = old_tabulation <% end %>
194
- result
195
- <% end %>
196
- <% end %>
197
- RUBY
198
-
199
132
  def attributes(class_id, obj_ref, *attributes_hashes)
200
133
  attributes = class_id
201
134
  attributes_hashes.each do |old|
202
- self.class.merge_attrs(attributes, Hash[old.map {|k, v| [k.to_s, v]}])
135
+ AttributeBuilder.merge_attributes!(attributes, Hash[old.map {|k, v| [k.to_s, v]}])
203
136
  end
204
- self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref
205
- Compiler.build_attributes(
137
+ AttributeBuilder.merge_attributes!(attributes, parse_object_ref(obj_ref)) if obj_ref
138
+ AttributeBuilder.build_attributes(
206
139
  html?, @options[:attr_wrapper], @options[:escape_attrs], @options[:hyphenate_data_attrs], attributes)
207
140
  end
208
141
 
@@ -217,50 +150,6 @@ RUBY
217
150
  buffer << buffer.slice!(capture_position..-1).rstrip
218
151
  end
219
152
 
220
- # Merges two attribute hashes.
221
- # This is the same as `to.merge!(from)`,
222
- # except that it merges id, class, and data attributes.
223
- #
224
- # ids are concatenated with `"_"`,
225
- # and classes are concatenated with `" "`.
226
- # data hashes are simply merged.
227
- #
228
- # Destructively modifies both `to` and `from`.
229
- #
230
- # @param to [{String => String}] The attribute hash to merge into
231
- # @param from [{String => #to_s}] The attribute hash to merge from
232
- # @return [{String => String}] `to`, after being merged
233
- def self.merge_attrs(to, from)
234
- from['id'] = Compiler.filter_and_join(from['id'], '_') if from['id']
235
- if to['id'] && from['id']
236
- to['id'] << '_' << from.delete('id').to_s
237
- elsif to['id'] || from['id']
238
- from['id'] ||= to['id']
239
- end
240
-
241
- from['class'] = Compiler.filter_and_join(from['class'], ' ') if from['class']
242
- if to['class'] && from['class']
243
- # Make sure we don't duplicate class names
244
- from['class'] = (from['class'].to_s.split(' ') | to['class'].split(' ')).sort.join(' ')
245
- elsif to['class'] || from['class']
246
- from['class'] ||= to['class']
247
- end
248
-
249
- from_data = from.delete('data') || {}
250
- to_data = to.delete('data') || {}
251
-
252
- # forces to_data & from_data into a hash
253
- from_data = { nil => from_data } unless from_data.is_a?(Hash)
254
- to_data = { nil => to_data } unless to_data.is_a?(Hash)
255
-
256
- merged_data = to_data.merge(from_data)
257
-
258
- to['data'] = merged_data unless merged_data.empty?
259
- to.merge!(from)
260
- end
261
-
262
- private
263
-
264
153
  # Works like #{find_and_preserve}, but allows the first newline after a
265
154
  # preserved opening tag to remain unencoded, and then outdents the content.
266
155
  # This change was motivated primarily by the change in Rails 3.2.3 to emit
@@ -270,6 +159,8 @@ RUBY
270
159
  # @since Haml 4.0.1
271
160
  # @private
272
161
  def fix_textareas!(input)
162
+ return input unless input.include?('<textarea'.freeze)
163
+
273
164
  pattern = /<(textarea)([^>]*)>(\n|&#x000A;)(.*?)<\/textarea>/im
274
165
  input.gsub!(pattern) do |s|
275
166
  match = pattern.match(s)
@@ -281,16 +172,13 @@ RUBY
281
172
  end
282
173
  "<#{match[1]}#{match[2]}>\n#{content}</#{match[1]}>"
283
174
  end
175
+ input
284
176
  end
285
177
 
286
- if RUBY_VERSION < "1.9"
287
- def new_encoded_string
288
- ""
289
- end
290
- else
291
- def new_encoded_string
292
- "".encode(Encoding.find(options[:encoding]))
293
- end
178
+ private
179
+
180
+ def new_encoded_string
181
+ "".encode(options[:encoding])
294
182
  end
295
183
 
296
184
  @@tab_cache = {}
@@ -328,18 +216,20 @@ RUBY
328
216
  id = "#{ prefix }_#{ id }"
329
217
  end
330
218
 
331
- {'id' => id, 'class' => class_name}
219
+ { 'id'.freeze => id, 'class'.freeze => class_name }
332
220
  end
333
221
 
334
222
  # Changes a word from camel case to underscores.
335
223
  # Based on the method of the same name in Rails' Inflector,
336
224
  # but copied here so it'll run properly without Rails.
337
225
  def underscore(camel_cased_word)
338
- camel_cased_word.to_s.gsub(/::/, '_').
339
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
340
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
341
- tr("-", "_").
342
- downcase
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
343
233
  end
344
234
  end
345
235
  end