haml 4.0.7 → 5.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +18 -0
- data/.gitmodules +3 -0
- data/.travis.yml +54 -0
- data/.yardopts +1 -1
- data/CHANGELOG.md +96 -4
- data/FAQ.md +4 -14
- data/Gemfile +19 -0
- data/MIT-LICENSE +1 -1
- data/README.md +80 -42
- data/REFERENCE.md +116 -64
- data/Rakefile +46 -54
- data/TODO +24 -0
- data/benchmark.rb +66 -0
- data/haml.gemspec +38 -0
- data/lib/haml/.gitattributes +1 -0
- data/lib/haml/attribute_builder.rb +163 -0
- data/lib/haml/attribute_compiler.rb +223 -0
- data/lib/haml/attribute_parser.rb +148 -0
- data/lib/haml/buffer.rb +22 -132
- data/lib/haml/compiler.rb +89 -298
- 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 +38 -19
- data/lib/haml/filters.rb +18 -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 +42 -60
- data/lib/haml/helpers/action_view_xss_mods.rb +1 -0
- data/lib/haml/helpers/safe_erubi_template.rb +19 -0
- data/lib/haml/helpers/safe_erubis_template.rb +4 -1
- data/lib/haml/helpers/xss_mods.rb +18 -12
- data/lib/haml/helpers.rb +132 -89
- data/lib/haml/options.rb +41 -47
- data/lib/haml/parser.rb +278 -216
- data/lib/haml/{template/plugin.rb → plugin.rb} +8 -15
- data/lib/haml/railtie.rb +38 -12
- 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 +121 -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 +1 -0
- data/yard/default/.gitignore +1 -0
- data/yard/default/fulldoc/html/css/common.sass +15 -0
- data/yard/default/layout/html/footer.erb +12 -0
- metadata +50 -111
- data/test/engine_test.rb +0 -2013
- data/test/erb/_av_partial_1.erb +0 -12
- data/test/erb/_av_partial_2.erb +0 -8
- data/test/erb/action_view.erb +0 -62
- data/test/erb/standard.erb +0 -55
- data/test/filters_test.rb +0 -254
- 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-4.0.x +0 -5
- data/test/haml-spec/LICENSE +0 -14
- data/test/haml-spec/README.md +0 -106
- data/test/haml-spec/lua_haml_spec.lua +0 -38
- data/test/haml-spec/perl_haml_test.pl +0 -81
- data/test/haml-spec/ruby_haml_test.rb +0 -23
- data/test/haml-spec/tests.json +0 -660
- data/test/helper_test.rb +0 -583
- data/test/markaby/standard.mab +0 -52
- data/test/mocks/article.rb +0 -6
- data/test/parser_test.rb +0 -105
- data/test/results/content_for_layout.xhtml +0 -12
- data/test/results/eval_suppressed.xhtml +0 -9
- data/test/results/helpers.xhtml +0 -70
- data/test/results/helpful.xhtml +0 -10
- data/test/results/just_stuff.xhtml +0 -70
- data/test/results/list.xhtml +0 -12
- data/test/results/nuke_inner_whitespace.xhtml +0 -40
- data/test/results/nuke_outer_whitespace.xhtml +0 -148
- data/test/results/original_engine.xhtml +0 -20
- data/test/results/partial_layout.xhtml +0 -5
- data/test/results/partial_layout_erb.xhtml +0 -5
- data/test/results/partials.xhtml +0 -21
- data/test/results/render_layout.xhtml +0 -3
- data/test/results/silent_script.xhtml +0 -74
- data/test/results/standard.xhtml +0 -162
- data/test/results/tag_parsing.xhtml +0 -23
- data/test/results/very_basic.xhtml +0 -5
- data/test/results/whitespace_handling.xhtml +0 -90
- data/test/template_test.rb +0 -354
- data/test/templates/_av_partial_1.haml +0 -9
- data/test/templates/_av_partial_1_ugly.haml +0 -9
- data/test/templates/_av_partial_2.haml +0 -5
- data/test/templates/_av_partial_2_ugly.haml +0 -5
- data/test/templates/_layout.erb +0 -3
- data/test/templates/_layout_for_partial.haml +0 -3
- data/test/templates/_partial.haml +0 -8
- data/test/templates/_text_area.haml +0 -3
- data/test/templates/_text_area_helper.html.haml +0 -4
- data/test/templates/action_view.haml +0 -47
- data/test/templates/action_view_ugly.haml +0 -47
- data/test/templates/breakage.haml +0 -8
- data/test/templates/content_for_layout.haml +0 -8
- data/test/templates/eval_suppressed.haml +0 -11
- data/test/templates/helpers.haml +0 -55
- data/test/templates/helpful.haml +0 -11
- data/test/templates/just_stuff.haml +0 -85
- data/test/templates/list.haml +0 -12
- data/test/templates/nuke_inner_whitespace.haml +0 -32
- data/test/templates/nuke_outer_whitespace.haml +0 -144
- data/test/templates/original_engine.haml +0 -17
- data/test/templates/partial_layout.haml +0 -3
- data/test/templates/partial_layout_erb.erb +0 -4
- data/test/templates/partialize.haml +0 -1
- data/test/templates/partials.haml +0 -12
- data/test/templates/render_layout.haml +0 -2
- data/test/templates/silent_script.haml +0 -45
- data/test/templates/standard.haml +0 -43
- data/test/templates/standard_ugly.haml +0 -43
- data/test/templates/tag_parsing.haml +0 -21
- data/test/templates/very_basic.haml +0 -4
- data/test/templates/whitespace_handling.haml +0 -87
- data/test/test_helper.rb +0 -81
- data/test/util_test.rb +0 -63
data/lib/haml/engine.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
require 'forwardable'
|
2
3
|
|
3
4
|
require 'haml/parser'
|
@@ -7,6 +8,7 @@ require 'haml/helpers'
|
|
7
8
|
require 'haml/buffer'
|
8
9
|
require 'haml/filters'
|
9
10
|
require 'haml/error'
|
11
|
+
require 'haml/temple_engine'
|
10
12
|
|
11
13
|
module Haml
|
12
14
|
# This is the frontend for using Haml programmatically.
|
@@ -35,9 +37,6 @@ module Haml
|
|
35
37
|
# @return [String]
|
36
38
|
attr_accessor :indentation
|
37
39
|
|
38
|
-
attr_accessor :compiler
|
39
|
-
attr_accessor :parser
|
40
|
-
|
41
40
|
# Tilt currently depends on these moved methods, provide a stable API
|
42
41
|
def_delegators :compiler, :precompiled, :precompiled_method_return_value
|
43
42
|
|
@@ -58,19 +57,19 @@ module Haml
|
|
58
57
|
raise Haml::Error.new(msg, line)
|
59
58
|
end
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
@compiler = @options.compiler_class.new(@options)
|
60
|
+
@temple_engine = TempleEngine.new(options)
|
61
|
+
@temple_engine.compile(@template)
|
62
|
+
end
|
65
63
|
|
66
|
-
|
64
|
+
# Deprecated API for backword compatibility
|
65
|
+
def compiler
|
66
|
+
@temple_engine
|
67
67
|
end
|
68
68
|
|
69
69
|
# Processes the template and returns the result as a string.
|
70
70
|
#
|
71
71
|
# `scope` is the context in which the template is evaluated.
|
72
|
-
# If it's a `Binding
|
73
|
-
# Haml uses it as the second argument to `Kernel#eval`;
|
72
|
+
# If it's a `Binding`, Haml uses it as the second argument to `Kernel#eval`;
|
74
73
|
# otherwise, Haml just uses its `#instance_eval` context.
|
75
74
|
#
|
76
75
|
# Note that Haml modifies the evaluation context
|
@@ -95,23 +94,23 @@ module Haml
|
|
95
94
|
# within the template.
|
96
95
|
#
|
97
96
|
# Due to some Ruby quirks,
|
98
|
-
# if `scope` is a `Binding`
|
97
|
+
# if `scope` is a `Binding` object and a block is given,
|
99
98
|
# the evaluation context may not be quite what the user expects.
|
100
99
|
# In particular, it's equivalent to passing `eval("self", scope)` as `scope`.
|
101
100
|
# This won't have an effect in most cases,
|
102
101
|
# but if you're relying on local variables defined in the context of `scope`,
|
103
102
|
# they won't work.
|
104
103
|
#
|
105
|
-
# @param scope [Binding,
|
104
|
+
# @param scope [Binding, Object] The context in which the template is evaluated
|
106
105
|
# @param locals [{Symbol => Object}] Local variables that will be made available
|
107
106
|
# to the template
|
108
107
|
# @param block [#to_proc] A block that can be yielded to within the template
|
109
108
|
# @return [String] The rendered template
|
110
109
|
def render(scope = Object.new, locals = {}, &block)
|
111
|
-
parent = scope.instance_variable_defined?(
|
110
|
+
parent = scope.instance_variable_defined?(:@haml_buffer) ? scope.instance_variable_get(:@haml_buffer) : nil
|
112
111
|
buffer = Haml::Buffer.new(parent, @options.for_buffer)
|
113
112
|
|
114
|
-
if scope.is_a?(Binding)
|
113
|
+
if scope.is_a?(Binding)
|
115
114
|
scope_object = eval("self", scope)
|
116
115
|
scope = scope_object.instance_eval{binding} if block_given?
|
117
116
|
else
|
@@ -121,20 +120,16 @@ module Haml
|
|
121
120
|
|
122
121
|
set_locals(locals.merge(:_hamlout => buffer, :_erbout => buffer.buffer), scope, scope_object)
|
123
122
|
|
124
|
-
scope_object.
|
125
|
-
|
126
|
-
@haml_buffer = buffer
|
127
|
-
end
|
123
|
+
scope_object.extend(Haml::Helpers)
|
124
|
+
scope_object.instance_variable_set(:@haml_buffer, buffer)
|
128
125
|
begin
|
129
|
-
eval(@
|
126
|
+
eval(@temple_engine.precompiled_with_return_value, scope, @options.filename, @options.line)
|
130
127
|
rescue ::SyntaxError => e
|
131
128
|
raise SyntaxError, e.message
|
132
129
|
end
|
133
130
|
ensure
|
134
131
|
# Get rid of the current buffer
|
135
|
-
scope_object.
|
136
|
-
@haml_buffer = buffer.upper if buffer
|
137
|
-
end
|
132
|
+
scope_object.instance_variable_set(:@haml_buffer, buffer.upper) if buffer
|
138
133
|
end
|
139
134
|
alias_method :to_html, :render
|
140
135
|
|
@@ -159,11 +154,11 @@ module Haml
|
|
159
154
|
#
|
160
155
|
# The proc doesn't take a block; any yields in the template will fail.
|
161
156
|
#
|
162
|
-
# @param scope [Binding,
|
157
|
+
# @param scope [Binding, Object] The context in which the template is evaluated
|
163
158
|
# @param local_names [Array<Symbol>] The names of the locals that can be passed to the proc
|
164
159
|
# @return [Proc] The proc that will run the template
|
165
160
|
def render_proc(scope = Object.new, *local_names)
|
166
|
-
if scope.is_a?(Binding)
|
161
|
+
if scope.is_a?(Binding)
|
167
162
|
scope_object = eval("self", scope)
|
168
163
|
else
|
169
164
|
scope_object = scope
|
@@ -171,8 +166,8 @@ module Haml
|
|
171
166
|
end
|
172
167
|
|
173
168
|
begin
|
174
|
-
eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};"
|
175
|
-
|
169
|
+
eval("Proc.new { |*_haml_locals| _haml_locals = _haml_locals[0] || {};" <<
|
170
|
+
@temple_engine.precompiled_with_ambles(local_names) << "}\n", scope, @options.filename, @options.line)
|
176
171
|
rescue ::SyntaxError => e
|
177
172
|
raise SyntaxError, e.message
|
178
173
|
end
|
@@ -182,7 +177,7 @@ module Haml
|
|
182
177
|
# that renders the template and returns the result as a string.
|
183
178
|
#
|
184
179
|
# If `object` is a class or module,
|
185
|
-
# the method will instead
|
180
|
+
# the method will instead be defined as an instance method.
|
186
181
|
# For example:
|
187
182
|
#
|
188
183
|
# t = Time.now
|
@@ -219,25 +214,14 @@ module Haml
|
|
219
214
|
def def_method(object, name, *local_names)
|
220
215
|
method = object.is_a?(Module) ? :module_eval : :instance_eval
|
221
216
|
|
222
|
-
object.send(method, "def #{name}(_haml_locals = {}); #{
|
223
|
-
@options
|
217
|
+
object.send(method, "def #{name}(_haml_locals = {}); #{@temple_engine.precompiled_with_ambles(local_names)}; end",
|
218
|
+
@options.filename, @options.line)
|
224
219
|
end
|
225
220
|
|
226
221
|
private
|
227
222
|
|
228
|
-
if RUBY_VERSION < "1.9"
|
229
|
-
def initialize_encoding(given_value)
|
230
|
-
end
|
231
|
-
else
|
232
|
-
def initialize_encoding(given_value)
|
233
|
-
unless given_value
|
234
|
-
@options.encoding = Encoding.default_internal || @template.encoding
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
223
|
def set_locals(locals, scope, scope_object)
|
240
|
-
scope_object.
|
224
|
+
scope_object.instance_variable_set :@_haml_locals, locals
|
241
225
|
set_locals = locals.keys.map { |k| "#{k} = @_haml_locals[#{k.inspect}]" }.join("\n")
|
242
226
|
eval(set_locals, scope)
|
243
227
|
end
|
data/lib/haml/error.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Haml
|
2
3
|
# An exception raised by Haml code.
|
3
4
|
class Error < StandardError
|
@@ -58,4 +59,6 @@ END
|
|
58
59
|
# It's not particularly interesting,
|
59
60
|
# except in that it's a subclass of {Haml::Error}.
|
60
61
|
class SyntaxError < Error; end
|
62
|
+
|
63
|
+
class InvalidAttributeNameError < SyntaxError; end
|
61
64
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
# Like Temple::Filters::Escapable, but with support for escaping by
|
4
|
+
# Haml::Herlpers.html_escape and Haml::Herlpers.escape_once.
|
5
|
+
class Escapable < Temple::Filter
|
6
|
+
def initialize(*)
|
7
|
+
super
|
8
|
+
@escape_code = "::Haml::Helpers.html_escape((%s))"
|
9
|
+
@escaper = eval("proc {|v| #{@escape_code % 'v'} }")
|
10
|
+
@once_escape_code = "::Haml::Helpers.escape_once((%s))"
|
11
|
+
@once_escaper = eval("proc {|v| #{@once_escape_code % 'v'} }")
|
12
|
+
@escape = false
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_escape(flag, exp)
|
16
|
+
old = @escape
|
17
|
+
@escape = flag
|
18
|
+
compile(exp)
|
19
|
+
ensure
|
20
|
+
@escape = old
|
21
|
+
end
|
22
|
+
|
23
|
+
# The same as Haml::AttributeBuilder.build_attributes
|
24
|
+
def on_static(value)
|
25
|
+
[:static,
|
26
|
+
if @escape == :once
|
27
|
+
@once_escaper[value]
|
28
|
+
elsif @escape
|
29
|
+
@escaper[value]
|
30
|
+
else
|
31
|
+
value
|
32
|
+
end
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
# The same as Haml::AttributeBuilder.build_attributes
|
37
|
+
def on_dynamic(value)
|
38
|
+
[:dynamic,
|
39
|
+
if @escape == :once
|
40
|
+
@once_escape_code % value
|
41
|
+
elsif @escape
|
42
|
+
@escape_code % value
|
43
|
+
else
|
44
|
+
"(#{value}).to_s"
|
45
|
+
end
|
46
|
+
]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/haml/exec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'optparse'
|
2
|
-
require 'fileutils'
|
3
3
|
require 'rbconfig'
|
4
4
|
require 'pp'
|
5
5
|
|
@@ -212,11 +212,6 @@ END
|
|
212
212
|
@options[:output] = StringIO.new
|
213
213
|
end
|
214
214
|
|
215
|
-
opts.on('-t', '--style NAME',
|
216
|
-
'Output style. Can be indented (default) or ugly.') do |name|
|
217
|
-
@options[:for_engine][:ugly] = true if name.to_sym == :ugly
|
218
|
-
end
|
219
|
-
|
220
215
|
opts.on('-f', '--format NAME',
|
221
216
|
'Output format. Can be html5 (default), xhtml, or html4.') do |name|
|
222
217
|
@options[:for_engine][:format] = name.to_sym
|
@@ -237,6 +232,11 @@ END
|
|
237
232
|
@options[:for_engine][:attr_wrapper] = '"'
|
238
233
|
end
|
239
234
|
|
235
|
+
opts.on('--remove-whitespace',
|
236
|
+
'Remove whitespace surrounding and within tags') do
|
237
|
+
@options[:for_engine][:remove_whitespace] = true
|
238
|
+
end
|
239
|
+
|
240
240
|
opts.on('--cdata',
|
241
241
|
'Always add CDATA sections to javascript and css blocks.') do
|
242
242
|
@options[:for_engine][:cdata] = true
|
@@ -260,15 +260,13 @@ END
|
|
260
260
|
@options[:load_paths] << path
|
261
261
|
end
|
262
262
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
Encoding.default_internal = internal if internal && !internal.empty?
|
268
|
-
end
|
263
|
+
opts.on('-E ex[:in]', 'Specify the default external and internal character encodings.') do |encoding|
|
264
|
+
external, internal = encoding.split(':')
|
265
|
+
Encoding.default_external = external if external && !external.empty?
|
266
|
+
Encoding.default_internal = internal if internal && !internal.empty?
|
269
267
|
end
|
270
268
|
|
271
|
-
opts.on('-d', '--debug', "Print out the precompiled Ruby source.") do
|
269
|
+
opts.on('-d', '--debug', "Print out the precompiled Ruby source, and show syntax errors in the Ruby code.") do
|
272
270
|
@options[:debug] = true
|
273
271
|
end
|
274
272
|
|
@@ -294,20 +292,33 @@ END
|
|
294
292
|
|
295
293
|
begin
|
296
294
|
|
297
|
-
|
298
|
-
|
299
|
-
|
295
|
+
if @options[:parse]
|
296
|
+
parser = ::Haml::Parser.new(::Haml::Options.new(@options))
|
297
|
+
pp parser.call(template)
|
300
298
|
return
|
301
299
|
end
|
302
300
|
|
303
|
-
|
304
|
-
|
301
|
+
engine = ::Haml::Engine.new(template, @options[:for_engine])
|
302
|
+
|
303
|
+
if @options[:check_syntax]
|
304
|
+
error = validate_ruby(engine.precompiled)
|
305
|
+
if error
|
306
|
+
puts error.message.split("\n").first
|
307
|
+
exit 1
|
308
|
+
end
|
309
|
+
puts "Syntax OK"
|
305
310
|
return
|
306
311
|
end
|
307
312
|
|
308
313
|
if @options[:debug]
|
309
314
|
puts engine.precompiled
|
310
|
-
|
315
|
+
error = validate_ruby(engine.precompiled)
|
316
|
+
if error
|
317
|
+
puts '=' * 100
|
318
|
+
puts error.message.split("\n")[0]
|
319
|
+
exit 1
|
320
|
+
end
|
321
|
+
return
|
311
322
|
end
|
312
323
|
|
313
324
|
result = engine.to_html
|
@@ -324,6 +335,14 @@ END
|
|
324
335
|
output.write(result)
|
325
336
|
output.close() if output.is_a? File
|
326
337
|
end
|
338
|
+
|
339
|
+
def validate_ruby(code)
|
340
|
+
begin
|
341
|
+
eval("BEGIN {return nil}; #{code}", binding, @options[:filename] || "")
|
342
|
+
rescue ::SyntaxError # Not to be confused with Haml::SyntaxError
|
343
|
+
$!
|
344
|
+
end
|
345
|
+
end
|
327
346
|
end
|
328
347
|
end
|
329
348
|
end
|
data/lib/haml/filters.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
require "tilt"
|
2
3
|
|
3
4
|
module Haml
|
@@ -59,7 +60,7 @@ module Haml
|
|
59
60
|
end
|
60
61
|
|
61
62
|
# Removes a filter from Haml. If the filter was removed, it returns
|
62
|
-
# the that was
|
63
|
+
# the Module that was removed upon success, or nil on failure. If you try
|
63
64
|
# to redefine a filter, Haml will raise an error. Use this method first to
|
64
65
|
# explicitly remove the filter before redefining it.
|
65
66
|
# @return Module The filter module that has been removed
|
@@ -163,10 +164,10 @@ module Haml
|
|
163
164
|
if contains_interpolation?(text)
|
164
165
|
return if options[:suppress_eval]
|
165
166
|
|
166
|
-
text = unescape_interpolation(text).gsub(/(\\+)n/) do |s|
|
167
|
+
text = unescape_interpolation(text, options[:escape_html]).gsub(/(\\+)n/) do |s|
|
167
168
|
escapes = $1.size
|
168
169
|
next s if escapes % 2 == 0
|
169
|
-
|
170
|
+
"#{'\\' * (escapes - 1)}\n"
|
170
171
|
end
|
171
172
|
# We need to add a newline at the beginning to get the
|
172
173
|
# filter lines to line up (since the Haml filter contains
|
@@ -174,7 +175,7 @@ module Haml
|
|
174
175
|
# filter name). Then we need to escape the trailing
|
175
176
|
# newline so that the whole filter block doesn't take up
|
176
177
|
# too many.
|
177
|
-
text =
|
178
|
+
text = %[\n#{text.sub(/\n"\Z/, "\\n\"")}]
|
178
179
|
push_script <<RUBY.rstrip, :escape_html => false
|
179
180
|
find_and_preserve(#{filter.inspect}.render_with_options(#{text}, _hamlout.options))
|
180
181
|
RUBY
|
@@ -182,12 +183,8 @@ RUBY
|
|
182
183
|
end
|
183
184
|
|
184
185
|
rendered = Haml::Helpers::find_and_preserve(filter.render_with_options(text, compiler.options), compiler.options[:preserve])
|
185
|
-
|
186
|
-
|
187
|
-
push_text(rendered.rstrip)
|
188
|
-
else
|
189
|
-
push_text(rendered.rstrip.gsub("\n", "\n#{' ' * @output_tabs}"))
|
190
|
-
end
|
186
|
+
rendered.rstrip!
|
187
|
+
push_text("#{rendered}\n")
|
191
188
|
end
|
192
189
|
end
|
193
190
|
end
|
@@ -216,13 +213,10 @@ RUBY
|
|
216
213
|
type = " type=#{options[:attr_wrapper]}text/javascript#{options[:attr_wrapper]}"
|
217
214
|
end
|
218
215
|
|
219
|
-
|
220
|
-
|
221
|
-
str << "#{indent}#{text.rstrip.gsub("\n", "\n#{indent}")}\n"
|
222
|
-
str << " //]]>\n" if options[:cdata]
|
223
|
-
str << "</script>"
|
216
|
+
text = text.rstrip
|
217
|
+
text.gsub!("\n", "\n#{indent}")
|
224
218
|
|
225
|
-
|
219
|
+
%!<script#{type}>\n#{" //<![CDATA[\n" if options[:cdata]}#{indent}#{text}\n#{" //]]>\n" if options[:cdata]}</script>!
|
226
220
|
end
|
227
221
|
end
|
228
222
|
|
@@ -240,13 +234,10 @@ RUBY
|
|
240
234
|
type = " type=#{options[:attr_wrapper]}text/css#{options[:attr_wrapper]}"
|
241
235
|
end
|
242
236
|
|
243
|
-
|
244
|
-
|
245
|
-
str << "#{indent}#{text.rstrip.gsub("\n", "\n#{indent}")}\n"
|
246
|
-
str << " /*]]>*/\n" if options[:cdata]
|
247
|
-
str << "</style>"
|
237
|
+
text = text.rstrip
|
238
|
+
text.gsub!("\n", "\n#{indent}")
|
248
239
|
|
249
|
-
|
240
|
+
%(<style#{type}>\n#{" /*<![CDATA[*/\n" if options[:cdata]}#{indent}#{text}\n#{" /*]]>*/\n" if options[:cdata]}</style>)
|
250
241
|
end
|
251
242
|
end
|
252
243
|
|
@@ -256,7 +247,10 @@ RUBY
|
|
256
247
|
|
257
248
|
# @see Base#render
|
258
249
|
def render(text)
|
259
|
-
|
250
|
+
text = "\n#{text}"
|
251
|
+
text.rstrip!
|
252
|
+
text.gsub!("\n", "\n ")
|
253
|
+
"<![CDATA[#{text}\n]]>"
|
260
254
|
end
|
261
255
|
end
|
262
256
|
|
@@ -288,7 +282,7 @@ RUBY
|
|
288
282
|
def compile(compiler, text)
|
289
283
|
return if compiler.options[:suppress_eval]
|
290
284
|
compiler.instance_eval do
|
291
|
-
push_silent <<-FIRST.
|
285
|
+
push_silent "#{<<-FIRST.tr("\n", ';')}#{text}#{<<-LAST.tr("\n", ';')}"
|
292
286
|
begin
|
293
287
|
haml_io = StringIO.new(_hamlout.buffer, 'a')
|
294
288
|
FIRST
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
module Haml
|
3
|
+
# Ruby code generator, which is a limited version of Temple::Generator.
|
4
|
+
# Limit methods since Haml doesn't need most of them.
|
5
|
+
class Generator
|
6
|
+
include Temple::Mixins::CompiledDispatcher
|
7
|
+
include Temple::Mixins::Options
|
8
|
+
|
9
|
+
define_options freeze_static: RUBY_VERSION >= '2.1'
|
10
|
+
|
11
|
+
def call(exp)
|
12
|
+
compile(exp)
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_multi(*exp)
|
16
|
+
exp.map { |e| compile(e) }.join('; ')
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_static(text)
|
20
|
+
concat(options[:freeze_static] ? "#{Util.inspect_obj(text)}.freeze" : Util.inspect_obj(text))
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_dynamic(code)
|
24
|
+
concat(code)
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_code(exp)
|
28
|
+
exp
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_newline
|
32
|
+
"\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def concat(str)
|
38
|
+
"_hamlout.buffer << (#{str});"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Haml
|
2
3
|
module Helpers
|
3
4
|
@@action_view_defined = true
|
@@ -32,7 +33,7 @@ module Haml
|
|
32
33
|
#
|
33
34
|
# @return [String] The class name for the current page
|
34
35
|
def page_class
|
35
|
-
controller.controller_name
|
36
|
+
"#{controller.controller_name} #{controller.action_name}"
|
36
37
|
end
|
37
38
|
alias_method :generate_content_class_names, :page_class
|
38
39
|
|
@@ -45,7 +46,7 @@ module Haml
|
|
45
46
|
# @yield A block in which all input to `#haml_concat` is treated as raw.
|
46
47
|
# @see Haml::Util#rails_xss_safe?
|
47
48
|
def with_raw_haml_concat
|
48
|
-
old = instance_variable_defined?(
|
49
|
+
old = instance_variable_defined?(:@_haml_concat_raw) ? @_haml_concat_raw : false
|
49
50
|
@_haml_concat_raw = true
|
50
51
|
yield
|
51
52
|
ensure
|
@@ -1,40 +1,40 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Haml
|
3
|
+
module Helpers
|
4
|
+
module ActionViewMods
|
5
|
+
def render(*args, &block)
|
6
|
+
options = args.first
|
7
|
+
|
8
|
+
# If render :layout is used with a block, it concats rather than returning
|
9
|
+
# a string so we need it to keep thinking it's Haml until it hits the
|
10
|
+
# sub-render.
|
11
|
+
if is_haml? && !(options.is_a?(Hash) && options[:layout] && block_given?)
|
12
|
+
return non_haml { super }
|
13
|
+
end
|
14
|
+
super
|
11
15
|
end
|
12
|
-
render_without_haml(*args, &block)
|
13
|
-
end
|
14
|
-
alias_method :render_without_haml, :render
|
15
|
-
alias_method :render, :render_with_haml
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
alias_method :output_buffer_without_haml, :output_buffer
|
22
|
-
alias_method :output_buffer, :output_buffer_with_haml
|
17
|
+
def output_buffer
|
18
|
+
return haml_buffer.buffer if is_haml?
|
19
|
+
super
|
20
|
+
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
def output_buffer=(new_buffer)
|
23
|
+
if is_haml?
|
24
|
+
if Haml::Util.rails_xss_safe? && new_buffer.is_a?(ActiveSupport::SafeBuffer)
|
25
|
+
new_buffer = String.new(new_buffer)
|
26
|
+
end
|
27
|
+
haml_buffer.buffer = new_buffer
|
28
|
+
else
|
29
|
+
super
|
28
30
|
end
|
29
|
-
haml_buffer.buffer = new_buffer
|
30
|
-
else
|
31
|
-
set_output_buffer_without_haml new_buffer
|
32
31
|
end
|
33
32
|
end
|
34
|
-
|
35
|
-
alias_method :output_buffer=, :set_output_buffer_with_haml
|
33
|
+
ActionView::Base.send(:prepend, ActionViewMods)
|
36
34
|
end
|
35
|
+
end
|
37
36
|
|
37
|
+
module ActionView
|
38
38
|
module Helpers
|
39
39
|
module CaptureHelper
|
40
40
|
def capture_with_haml(*args, &block)
|
@@ -42,12 +42,7 @@ module ActionView
|
|
42
42
|
#double assignment is to avoid warnings
|
43
43
|
_hamlout = _hamlout = eval('_hamlout', block.binding) # Necessary since capture_haml checks _hamlout
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
# NonCattingString is present in Rails less than 3.1.0. When support
|
48
|
-
# for 3.0 is dropped, this can be removed.
|
49
|
-
return ActionView::NonConcattingString.new(str) if str && defined?(ActionView::NonConcattingString)
|
50
|
-
return str
|
45
|
+
capture_haml(*args, &block)
|
51
46
|
else
|
52
47
|
capture_without_haml(*args, &block)
|
53
48
|
end
|
@@ -60,14 +55,18 @@ module ActionView
|
|
60
55
|
def content_tag_with_haml(name, *args, &block)
|
61
56
|
return content_tag_without_haml(name, *args, &block) unless is_haml?
|
62
57
|
|
63
|
-
preserve = haml_buffer.options
|
58
|
+
preserve = haml_buffer.options.fetch(:preserve, %w[textarea pre code]).include?(name.to_s)
|
64
59
|
|
65
60
|
if block_given? && block_is_haml?(block) && preserve
|
66
|
-
return content_tag_without_haml(name, *args)
|
61
|
+
return content_tag_without_haml(name, *args) do
|
62
|
+
haml_buffer.fix_textareas!(Haml::Helpers.preserve(&block)).html_safe
|
63
|
+
end
|
67
64
|
end
|
68
65
|
|
69
66
|
content = content_tag_without_haml(name, *args, &block)
|
70
|
-
|
67
|
+
if preserve && content
|
68
|
+
content = haml_buffer.fix_textareas!(Haml::Helpers.preserve(content)).html_safe
|
69
|
+
end
|
71
70
|
content
|
72
71
|
end
|
73
72
|
|
@@ -87,11 +86,9 @@ module ActionView
|
|
87
86
|
end
|
88
87
|
end
|
89
88
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
include HamlSupport
|
94
|
-
end
|
89
|
+
module Tags
|
90
|
+
class TextArea
|
91
|
+
include HamlSupport
|
95
92
|
end
|
96
93
|
end
|
97
94
|
|
@@ -118,7 +115,7 @@ module ActionView
|
|
118
115
|
with_tabs(1) {oldproc.call(*args)}
|
119
116
|
end
|
120
117
|
end
|
121
|
-
res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc)
|
118
|
+
res = form_tag_without_haml(url_for_options, options, *parameters_for_url, &proc) << "\n"
|
122
119
|
res << "\n" if wrap_block
|
123
120
|
res
|
124
121
|
else
|
@@ -128,20 +125,5 @@ module ActionView
|
|
128
125
|
alias_method :form_tag_without_haml, :form_tag
|
129
126
|
alias_method :form_tag, :form_tag_with_haml
|
130
127
|
end
|
131
|
-
|
132
|
-
module FormHelper
|
133
|
-
def form_for_with_haml(object_name, *args, &proc)
|
134
|
-
wrap_block = block_given? && is_haml? && block_is_haml?(proc)
|
135
|
-
if wrap_block
|
136
|
-
oldproc = proc
|
137
|
-
proc = proc {|*subargs| with_tabs(1) {oldproc.call(*subargs)}}
|
138
|
-
end
|
139
|
-
res = form_for_without_haml(object_name, *args, &proc)
|
140
|
-
res << "\n" if wrap_block
|
141
|
-
res
|
142
|
-
end
|
143
|
-
alias_method :form_for_without_haml, :form_for
|
144
|
-
alias_method :form_for, :form_for_with_haml
|
145
|
-
end
|
146
128
|
end
|
147
|
-
end
|
129
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'action_view'
|
3
|
+
|
4
|
+
module Haml
|
5
|
+
class ErubiTemplateHandler < ActionView::Template::Handlers::ERB::Erubi
|
6
|
+
|
7
|
+
def initialize(*args, &blk)
|
8
|
+
@newline_pending = 0
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class SafeErubiTemplate < Tilt::ErubiTemplate
|
14
|
+
def prepare
|
15
|
+
@options.merge! engine_class: Haml::ErubiTemplateHandler
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|