haml 5.0.0.beta.2 → 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 +4 -4
- data/CHANGELOG.md +7 -1
- data/Rakefile +15 -11
- data/lib/haml.rb +1 -0
- data/lib/haml/attribute_compiler.rb +10 -9
- data/lib/haml/attribute_parser.rb +78 -46
- data/lib/haml/buffer.rb +7 -20
- data/lib/haml/compiler.rb +23 -13
- data/lib/haml/engine.rb +1 -0
- data/lib/haml/error.rb +1 -0
- data/lib/haml/escapable.rb +1 -0
- data/lib/haml/exec.rb +3 -2
- data/lib/haml/filters.rb +1 -0
- data/lib/haml/generator.rb +5 -0
- data/lib/haml/helpers.rb +1 -0
- data/lib/haml/helpers/action_view_extensions.rb +1 -0
- data/lib/haml/helpers/action_view_mods.rb +2 -1
- data/lib/haml/helpers/action_view_xss_mods.rb +1 -0
- data/lib/haml/helpers/safe_erubi_template.rb +1 -0
- data/lib/haml/helpers/safe_erubis_template.rb +2 -1
- data/lib/haml/helpers/xss_mods.rb +1 -0
- data/lib/haml/options.rb +1 -0
- data/lib/haml/parser.rb +43 -9
- data/lib/haml/plugin.rb +1 -0
- data/lib/haml/railtie.rb +19 -25
- data/lib/haml/sass_rails_filter.rb +17 -4
- data/lib/haml/template.rb +1 -0
- data/lib/haml/template/options.rb +12 -2
- data/lib/haml/temple_engine.rb +1 -0
- data/lib/haml/temple_line_counter.rb +1 -0
- data/lib/haml/util.rb +1 -1
- data/lib/haml/version.rb +2 -1
- data/test/attribute_parser_test.rb +48 -52
- data/test/engine_test.rb +6 -0
- data/test/options_test.rb +4 -3
- data/test/results/bemit.xhtml +4 -0
- data/test/template_test.rb +1 -1
- data/test/templates/bemit.haml +3 -0
- data/test/test_helper.rb +3 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fa1e64aca629e46493a148b6159feb77763ba0d
|
4
|
+
data.tar.gz: 912f3565b782829c0651604333a0d5fd823c45a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8e860a0fc047d158a7a1d08f349a5555ae9a0afd578327c16cca624c3c0425a323e40cc3185f8ba8fede3ed79d24babb44f634969a69707a46f27d92b925b15
|
7
|
+
data.tar.gz: f3e66b26cf401ac0081721f44322a4fe39c0b0c486d6b4b0dd7e665e483be86f6f1769a0c94ed00b2646e3d76fb7be0ebe2e40c75943c0a5774e38cb3f17a4e2
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# Haml Changelog
|
2
2
|
|
3
|
-
## 5.0.0
|
3
|
+
## 5.0.0
|
4
|
+
|
5
|
+
Released on April 26, 2017
|
6
|
+
([diff](https://github.com/haml/haml/compare/4.0.7...5.0.0)).
|
4
7
|
|
5
8
|
* Haml now requires Ruby 2.0.0 or above.
|
6
9
|
* Rails 3 is no longer supported, matching the official
|
@@ -18,9 +21,12 @@
|
|
18
21
|
to the source Haml file from which it was generated. Thanks [Alex Babkin](https://github.com/ababkin).
|
19
22
|
* Fix #@foo and #$foo style interpolation that was not working in html_safe mode. (Akira Matsuda)
|
20
23
|
* Add `haml_tag_if` to render a block, conditionally wrapped in another element (Matt Wildig)
|
24
|
+
* Escape Ruby script interpolated in filters. (Matt Wildig)
|
21
25
|
* The `haml` command's debug option (`-d`) no longer executes the Haml code, but
|
22
26
|
rather checks the generated Ruby syntax for errors.
|
23
27
|
* Support Rails 5.1 Erubi template handler.
|
28
|
+
* Support Sprockets 3. Thanks [Sam Davies](https://github.com/samphilipd) and [Jeremy Venezia](https://github.com/jvenezia).
|
29
|
+
* Allow `@` as tag's class name. Thanks [Joe Bartlett](https://github.com/redoPop).
|
24
30
|
* Raise `Haml::InvalidAttributeNameError` when attribute name includes invalid characters. (Takashi Kokubun)
|
25
31
|
* Drop dynamic quotes support and always escape `'` for `escape_html`/`escape_attrs` instead.
|
26
32
|
Also, escaped results are slightly changed and always unified to the same characters. (Takashi Kokubun)
|
data/Rakefile
CHANGED
@@ -4,6 +4,21 @@ require "bundler/gem_tasks"
|
|
4
4
|
|
5
5
|
task :default => :test
|
6
6
|
|
7
|
+
# FIXME: Redefining :test task to run test/options_test.rb in isolated process since it depends on whether Rails is loaded or not.
|
8
|
+
# Remove this task when we finished changing escape_html option to be true by default.
|
9
|
+
isolated_test = Rake::TestTask.new do |t|
|
10
|
+
t.libs << 'test'
|
11
|
+
t.test_files = %w[test/options_test.rb]
|
12
|
+
t.warning = true
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
Rake::TestTask.new do |t|
|
16
|
+
t.libs << 'test'
|
17
|
+
t.test_files = Dir['test/*_test.rb'] + Dir['test/haml-spec/*_test.rb'] - isolated_test.file_list
|
18
|
+
t.warning = true
|
19
|
+
t.verbose = true
|
20
|
+
end
|
21
|
+
|
7
22
|
CLEAN.replace %w(pkg doc coverage .yardoc test/haml vendor)
|
8
23
|
|
9
24
|
desc "Benchmark Haml against ERB. TIMES=n sets the number of runs, default is 1000."
|
@@ -11,17 +26,6 @@ task :benchmark do
|
|
11
26
|
sh "ruby benchmark.rb #{ENV['TIMES']}"
|
12
27
|
end
|
13
28
|
|
14
|
-
Rake::TestTask.new do |t|
|
15
|
-
t.libs << 'lib' << 'test'
|
16
|
-
# haml-spec tests are explicitly added after other tests so they don't
|
17
|
-
# interfere with the Haml loading process which can cause test failures
|
18
|
-
files = Dir["test/*_test.rb"]
|
19
|
-
files.concat(Dir['test/haml-spec/*_test.rb'])
|
20
|
-
t.test_files = files
|
21
|
-
t.warning = true
|
22
|
-
t.verbose = true
|
23
|
-
end
|
24
|
-
|
25
29
|
task :set_coverage_env do
|
26
30
|
ENV["COVERAGE"] = "true"
|
27
31
|
end
|
data/lib/haml.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'haml/attribute_parser'
|
2
3
|
|
3
4
|
module Haml
|
@@ -27,10 +28,10 @@ module Haml
|
|
27
28
|
#
|
28
29
|
# @param attributes [Hash]
|
29
30
|
# @param object_ref [String,:nil]
|
30
|
-
# @param
|
31
|
+
# @param dynamic_attributes [DynamicAttributes]
|
31
32
|
# @return [String] Attributes rendering code
|
32
|
-
def self.runtime_build(attributes, object_ref,
|
33
|
-
"_hamlout.attributes(#{Haml::Util.inspect_obj(attributes)}, #{object_ref},#{
|
33
|
+
def self.runtime_build(attributes, object_ref, dynamic_attributes)
|
34
|
+
"_hamlout.attributes(#{Haml::Util.inspect_obj(attributes)}, #{object_ref},#{dynamic_attributes.to_literal})"
|
34
35
|
end
|
35
36
|
|
36
37
|
# @param options [Haml::Options]
|
@@ -45,16 +46,16 @@ module Haml
|
|
45
46
|
#
|
46
47
|
# @param attributes [Hash]
|
47
48
|
# @param object_ref [String,:nil]
|
48
|
-
# @param
|
49
|
+
# @param dynamic_attributes [DynamicAttributes]
|
49
50
|
# @return [Array] Temple expression
|
50
|
-
def compile(attributes, object_ref,
|
51
|
+
def compile(attributes, object_ref, dynamic_attributes)
|
51
52
|
if object_ref != :nil || !AttributeParser.available?
|
52
|
-
return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref,
|
53
|
+
return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref, dynamic_attributes)]
|
53
54
|
end
|
54
55
|
|
55
|
-
parsed_hashes =
|
56
|
+
parsed_hashes = [dynamic_attributes.new, dynamic_attributes.old].compact.map do |attribute_hash|
|
56
57
|
unless (hash = AttributeParser.parse(attribute_hash))
|
57
|
-
return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref,
|
58
|
+
return [:dynamic, AttributeCompiler.runtime_build(attributes, object_ref, dynamic_attributes)]
|
58
59
|
end
|
59
60
|
hash
|
60
61
|
end
|
@@ -69,7 +70,7 @@ module Haml
|
|
69
70
|
|
70
71
|
private
|
71
72
|
|
72
|
-
# Returns array of AttributeValue
|
73
|
+
# Returns array of AttributeValue instances from static attributes and dynamic_attributes. For each key,
|
73
74
|
# the values' order in returned value is preserved in the same order as Haml::Buffer#attributes's merge order.
|
74
75
|
#
|
75
76
|
# @param attributes [{ String => String }]
|
@@ -1,27 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
begin
|
2
3
|
require 'ripper'
|
3
4
|
rescue LoadError
|
4
5
|
end
|
5
6
|
|
6
7
|
module Haml
|
8
|
+
# Haml::AttriubuteParser parses Hash literal to { String (key name) => String (value literal) }.
|
7
9
|
module AttributeParser
|
8
10
|
class UnexpectedTokenError < StandardError; end
|
9
11
|
class UnexpectedKeyError < StandardError; end
|
10
12
|
|
13
|
+
# Indices in Ripper tokens
|
14
|
+
TYPE = 1
|
15
|
+
TEXT = 2
|
16
|
+
|
17
|
+
IGNORED_TYPES = %i[on_sp on_ignored_nl]
|
18
|
+
|
11
19
|
class << self
|
20
|
+
# @return [Boolean] - return true if AttributeParser.parse can be used.
|
12
21
|
def available?
|
13
22
|
defined?(Ripper) && Temple::StaticAnalyzer.available?
|
14
23
|
end
|
15
24
|
|
16
|
-
|
17
|
-
|
18
|
-
|
25
|
+
# @param [String] exp - Old attributes literal or Hash literal generated from new attributes.
|
26
|
+
# @return [Hash<String, String>,nil] - Return parsed attribute Hash whose values are Ruby literals, or return nil if argument is not a single Hash literal.
|
27
|
+
def parse(exp)
|
28
|
+
return nil unless hash_literal?(exp)
|
19
29
|
|
20
30
|
hash = {}
|
21
|
-
|
22
|
-
|
23
|
-
key = parse_key!(attr_tokens)
|
24
|
-
hash[key] = attr_tokens.map(&:last).join.strip
|
31
|
+
each_attribute(exp) do |key, value|
|
32
|
+
hash[key] = value
|
25
33
|
end
|
26
34
|
hash
|
27
35
|
rescue UnexpectedTokenError, UnexpectedKeyError
|
@@ -30,82 +38,106 @@ module Haml
|
|
30
38
|
|
31
39
|
private
|
32
40
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
# @param [String] exp - Ruby expression
|
42
|
+
# @return [Boolean] - Return true if exp is a single Hash literal
|
43
|
+
def hash_literal?(exp)
|
44
|
+
return false if Temple::StaticAnalyzer.syntax_error?(exp)
|
45
|
+
sym, body = Ripper.sexp(exp)
|
46
|
+
sym == :program && body.is_a?(Array) && body.size == 1 && body[0] && body[0][0] == :hash
|
37
47
|
end
|
38
48
|
|
39
|
-
|
40
|
-
|
49
|
+
# @param [Array] tokens - Ripper tokens. Scanned tokens will be destructively removed from this argument.
|
50
|
+
# @return [String] - attribute name in String
|
51
|
+
def shift_key!(tokens)
|
52
|
+
while !tokens.empty? && IGNORED_TYPES.include?(tokens.first[TYPE])
|
53
|
+
tokens.shift # ignore spaces
|
54
|
+
end
|
55
|
+
|
56
|
+
_, type, first_text = tokens.shift
|
41
57
|
case type
|
42
|
-
when :
|
43
|
-
|
44
|
-
when :
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
58
|
+
when :on_label # `key:`
|
59
|
+
first_text.tr(':', '')
|
60
|
+
when :on_symbeg # `:key =>`, `:'key' =>` or `:"key" =>`
|
61
|
+
key = tokens.shift[TEXT]
|
62
|
+
if first_text != ':' # `:'key'` or `:"key"`
|
63
|
+
expect_string_end!(tokens.shift)
|
64
|
+
end
|
65
|
+
shift_hash_rocket!(tokens)
|
50
66
|
key
|
51
|
-
when :on_tstring_beg
|
52
|
-
|
67
|
+
when :on_tstring_beg # `"key":`, `'key':` or `"key" =>`
|
68
|
+
key = tokens.shift[TEXT]
|
53
69
|
next_token = tokens.shift
|
54
|
-
|
55
|
-
|
56
|
-
|
70
|
+
if next_token[TYPE] != :on_label_end # on_label_end is `":` or `':`, so `"key" =>`
|
71
|
+
expect_string_end!(next_token)
|
72
|
+
shift_hash_rocket!(tokens)
|
57
73
|
end
|
58
74
|
key
|
59
75
|
else
|
60
|
-
raise UnexpectedKeyError
|
76
|
+
raise UnexpectedKeyError.new("unexpected token is given!: #{first_text} (#{type})")
|
61
77
|
end
|
62
78
|
end
|
63
79
|
|
64
|
-
|
65
|
-
|
80
|
+
# @param [Array] token - Ripper token
|
81
|
+
def expect_string_end!(token)
|
82
|
+
if token[TYPE] != :on_tstring_end
|
83
|
+
raise UnexpectedTokenError
|
84
|
+
end
|
66
85
|
end
|
67
86
|
|
68
|
-
|
87
|
+
# @param [Array] tokens - Ripper tokens
|
88
|
+
def shift_hash_rocket!(tokens)
|
69
89
|
until tokens.empty?
|
70
90
|
_, type, str = tokens.shift
|
71
91
|
break if type == :on_op && str == '=>'
|
72
92
|
end
|
73
93
|
end
|
74
94
|
|
75
|
-
|
95
|
+
# @param [String] hash_literal
|
96
|
+
# @param [Proc] block - that takes [String, String] as arguments
|
97
|
+
def each_attribute(hash_literal, &block)
|
98
|
+
all_tokens = Ripper.lex(hash_literal.strip)
|
99
|
+
all_tokens = all_tokens[1...-1] || [] # strip tokens for brackets
|
100
|
+
|
101
|
+
each_balaned_tokens(all_tokens) do |tokens|
|
102
|
+
key = shift_key!(tokens)
|
103
|
+
value = tokens.map(&:last).join.strip
|
104
|
+
block.call(key, value)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param [Array] tokens - Ripper tokens
|
109
|
+
# @param [Proc] block - that takes balanced Ripper tokens as arguments
|
110
|
+
def each_balaned_tokens(tokens, &block)
|
76
111
|
attr_tokens = []
|
77
|
-
|
78
|
-
brace_open = 0
|
79
|
-
paren_open = 0
|
112
|
+
open_tokens = Hash.new { |h, k| h[k] = 0 }
|
80
113
|
|
81
114
|
tokens.each do |token|
|
82
|
-
|
83
|
-
case type
|
115
|
+
case token[TYPE]
|
84
116
|
when :on_comma
|
85
|
-
if
|
86
|
-
|
117
|
+
if open_tokens.values.all?(&:zero?)
|
118
|
+
block.call(attr_tokens)
|
87
119
|
attr_tokens = []
|
88
120
|
next
|
89
121
|
end
|
90
122
|
when :on_lbracket
|
91
|
-
|
123
|
+
open_tokens[:array] += 1
|
92
124
|
when :on_rbracket
|
93
|
-
|
125
|
+
open_tokens[:array] -= 1
|
94
126
|
when :on_lbrace
|
95
|
-
|
127
|
+
open_tokens[:block] += 1
|
96
128
|
when :on_rbrace
|
97
|
-
|
129
|
+
open_tokens[:block] -= 1
|
98
130
|
when :on_lparen
|
99
|
-
|
131
|
+
open_tokens[:paren] += 1
|
100
132
|
when :on_rparen
|
101
|
-
|
102
|
-
when
|
133
|
+
open_tokens[:paren] -= 1
|
134
|
+
when *IGNORED_TYPES
|
103
135
|
next if attr_tokens.empty?
|
104
136
|
end
|
105
137
|
|
106
138
|
attr_tokens << token
|
107
139
|
end
|
108
|
-
|
140
|
+
block.call(attr_tokens) unless attr_tokens.empty?
|
109
141
|
end
|
110
142
|
end
|
111
143
|
end
|
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.
|
@@ -128,17 +129,6 @@ module Haml
|
|
128
129
|
@real_tabs += tab_change
|
129
130
|
end
|
130
131
|
|
131
|
-
# the number of arguments here is insane, but passing in an options hash instead of named arguments
|
132
|
-
# causes a significant performance regression
|
133
|
-
def format_script(result, preserve_script, in_tag, preserve_tag, escape_html, nuke_inner_whitespace, interpolated)
|
134
|
-
result_name = escape_html ? html_escape(result.to_s) : result.to_s
|
135
|
-
|
136
|
-
result = nuke_inner_whitespace ? result_name.strip : result_name
|
137
|
-
result = preserve(result, preserve_script, preserve_tag)
|
138
|
-
fix_textareas!(result) if toplevel? && result.include?('<textarea')
|
139
|
-
result
|
140
|
-
end
|
141
|
-
|
142
132
|
def attributes(class_id, obj_ref, *attributes_hashes)
|
143
133
|
attributes = class_id
|
144
134
|
attributes_hashes.each do |old|
|
@@ -160,14 +150,6 @@ module Haml
|
|
160
150
|
buffer << buffer.slice!(capture_position..-1).rstrip
|
161
151
|
end
|
162
152
|
|
163
|
-
private
|
164
|
-
|
165
|
-
def preserve(result, preserve_script, preserve_tag)
|
166
|
-
return Haml::Helpers.preserve(result) if preserve_tag
|
167
|
-
return Haml::Helpers.find_and_preserve(result, options[:preserve]) if preserve_script
|
168
|
-
result
|
169
|
-
end
|
170
|
-
|
171
153
|
# Works like #{find_and_preserve}, but allows the first newline after a
|
172
154
|
# preserved opening tag to remain unencoded, and then outdents the content.
|
173
155
|
# This change was motivated primarily by the change in Rails 3.2.3 to emit
|
@@ -177,6 +159,8 @@ module Haml
|
|
177
159
|
# @since Haml 4.0.1
|
178
160
|
# @private
|
179
161
|
def fix_textareas!(input)
|
162
|
+
return input unless toplevel? && input.include?('<textarea'.freeze)
|
163
|
+
|
180
164
|
pattern = /<(textarea)([^>]*)>(\n|
)(.*?)<\/textarea>/im
|
181
165
|
input.gsub!(pattern) do |s|
|
182
166
|
match = pattern.match(s)
|
@@ -188,10 +172,13 @@ module Haml
|
|
188
172
|
end
|
189
173
|
"<#{match[1]}#{match[2]}>\n#{content}</#{match[1]}>"
|
190
174
|
end
|
175
|
+
input
|
191
176
|
end
|
192
177
|
|
178
|
+
private
|
179
|
+
|
193
180
|
def new_encoded_string
|
194
|
-
"".encode(
|
181
|
+
"".encode(options[:encoding])
|
195
182
|
end
|
196
183
|
|
197
184
|
@@tab_cache = {}
|
data/lib/haml/compiler.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
require 'haml/attribute_builder'
|
2
3
|
require 'haml/attribute_compiler'
|
3
4
|
require 'haml/temple_line_counter'
|
@@ -92,13 +93,13 @@ module Haml
|
|
92
93
|
object_ref = :nil
|
93
94
|
parse = false
|
94
95
|
value = t[:parse] ? nil : t[:value]
|
95
|
-
|
96
|
+
dynamic_attributes = Haml::Parser::DynamicAttributes.new
|
96
97
|
preserve_script = false
|
97
98
|
else
|
98
99
|
object_ref = t[:object_ref]
|
99
100
|
parse = t[:parse]
|
100
101
|
value = t[:value]
|
101
|
-
|
102
|
+
dynamic_attributes = t[:dynamic_attributes]
|
102
103
|
preserve_script = t[:preserve_script]
|
103
104
|
end
|
104
105
|
|
@@ -107,7 +108,7 @@ module Haml
|
|
107
108
|
end
|
108
109
|
|
109
110
|
push_text("<#{t[:name]}")
|
110
|
-
push_temple(@attribute_compiler.compile(t[:attributes], object_ref,
|
111
|
+
push_temple(@attribute_compiler.compile(t[:attributes], object_ref, dynamic_attributes))
|
111
112
|
push_text(
|
112
113
|
if t[:self_closing] && @options.xhtml?
|
113
114
|
" />#{"\n" unless t[:nuke_outer_whitespace]}"
|
@@ -231,8 +232,7 @@ module Haml
|
|
231
232
|
|
232
233
|
def push_temple(temple)
|
233
234
|
flush_merged_text
|
234
|
-
|
235
|
-
@temple << [:code, newlines] unless newlines.empty?
|
235
|
+
@temple.concat([[:newline]] * resolve_newlines.count("\n"))
|
236
236
|
@temple << temple
|
237
237
|
@output_line += TempleLineCounter.count_lines(temple)
|
238
238
|
end
|
@@ -262,15 +262,10 @@ module Haml
|
|
262
262
|
def push_script(text, opts = {})
|
263
263
|
return if @options.suppress_eval?
|
264
264
|
|
265
|
-
args = [:preserve_script, :in_tag, :preserve_tag, :escape_html, :nuke_inner_whitespace]
|
266
|
-
args.map! {|name| !!opts[name]}
|
267
|
-
args << !block_given?
|
268
|
-
|
269
265
|
no_format = !(opts[:preserve_script] || opts[:preserve_tag] || opts[:escape_html])
|
270
266
|
|
271
267
|
unless block_given?
|
272
|
-
|
273
|
-
push_generated_script(no_format ? "(#{text}\n).to_s" : format_script_method)
|
268
|
+
push_generated_script(no_format ? "(#{text}\n).to_s" : build_script_formatter("(#{text}\n)", opts))
|
274
269
|
push_text("\n") unless opts[:in_tag] || opts[:nuke_inner_whitespace]
|
275
270
|
return
|
276
271
|
end
|
@@ -279,8 +274,23 @@ module Haml
|
|
279
274
|
push_silent "haml_temp = #{text}"
|
280
275
|
yield
|
281
276
|
push_silent('end', :can_suppress) unless @node.value[:dont_push_end]
|
282
|
-
|
283
|
-
|
277
|
+
@temple << [:dynamic, no_format ? 'haml_temp.to_s;' : build_script_formatter('haml_temp', opts)]
|
278
|
+
end
|
279
|
+
|
280
|
+
def build_script_formatter(text, opts)
|
281
|
+
text = "(#{text}).to_s"
|
282
|
+
if opts[:escape_html]
|
283
|
+
text = "::Haml::Helpers.html_escape(#{text})"
|
284
|
+
end
|
285
|
+
if opts[:nuke_inner_whitespace]
|
286
|
+
text = "(#{text}).strip"
|
287
|
+
end
|
288
|
+
if opts[:preserve_tag]
|
289
|
+
text = "::Haml::Helpers.preserve(#{text})"
|
290
|
+
elsif opts[:preserve_script]
|
291
|
+
text = "::Haml::Helpers.find_and_preserve(#{text}, _hamlout.options[:preserve])"
|
292
|
+
end
|
293
|
+
"_hamlout.fix_textareas!(#{text});"
|
284
294
|
end
|
285
295
|
|
286
296
|
def push_generated_script(text)
|
data/lib/haml/engine.rb
CHANGED
data/lib/haml/error.rb
CHANGED
data/lib/haml/escapable.rb
CHANGED
data/lib/haml/exec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'optparse'
|
2
3
|
require 'rbconfig'
|
3
4
|
require 'pp'
|
@@ -292,8 +293,8 @@ END
|
|
292
293
|
begin
|
293
294
|
|
294
295
|
if @options[:parse]
|
295
|
-
parser = ::Haml::Parser.new(
|
296
|
-
pp parser.
|
296
|
+
parser = ::Haml::Parser.new(::Haml::Options.new(@options))
|
297
|
+
pp parser.call(template)
|
297
298
|
return
|
298
299
|
end
|
299
300
|
|
data/lib/haml/filters.rb
CHANGED
data/lib/haml/generator.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Haml
|
2
3
|
# Ruby code generator, which is a limited version of Temple::Generator.
|
3
4
|
# Limit methods since Haml doesn't need most of them.
|
@@ -27,6 +28,10 @@ module Haml
|
|
27
28
|
exp
|
28
29
|
end
|
29
30
|
|
31
|
+
def on_newline
|
32
|
+
"\n"
|
33
|
+
end
|
34
|
+
|
30
35
|
private
|
31
36
|
|
32
37
|
def concat(str)
|
data/lib/haml/helpers.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Haml
|
2
3
|
module Helpers
|
3
4
|
module ActionViewMods
|
@@ -54,7 +55,7 @@ module ActionView
|
|
54
55
|
def content_tag_with_haml(name, *args, &block)
|
55
56
|
return content_tag_without_haml(name, *args, &block) unless is_haml?
|
56
57
|
|
57
|
-
preserve = haml_buffer.options
|
58
|
+
preserve = haml_buffer.options.fetch(:preserve, %w[textarea pre code]).include?(name.to_s)
|
58
59
|
|
59
60
|
if block_given? && block_is_haml?(block) && preserve
|
60
61
|
return content_tag_without_haml(name, *args) {preserve(&block)}
|
data/lib/haml/options.rb
CHANGED
data/lib/haml/parser.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
require 'strscan'
|
2
3
|
|
3
4
|
module Haml
|
@@ -204,6 +205,30 @@ module Haml
|
|
204
205
|
end
|
205
206
|
end
|
206
207
|
|
208
|
+
# @param [String] new - Hash literal including dynamic values.
|
209
|
+
# @param [String] old - Hash literal including dynamic values or Ruby literal of multiple Hashes which MUST be interpreted as method's last arguments.
|
210
|
+
class DynamicAttributes < Struct.new(:new, :old)
|
211
|
+
def old=(value)
|
212
|
+
unless value =~ /\A{.*}\z/m
|
213
|
+
raise ArgumentError.new('Old attributes must start with "{" and end with "}"')
|
214
|
+
end
|
215
|
+
super
|
216
|
+
end
|
217
|
+
|
218
|
+
# This will be a literal for Haml::Buffer#attributes's last argument, `attributes_hashes`.
|
219
|
+
def to_literal
|
220
|
+
[new, stripped_old].compact.join(', ')
|
221
|
+
end
|
222
|
+
|
223
|
+
private
|
224
|
+
|
225
|
+
# For `%foo{ { foo: 1 }, bar: 2 }`, :old is "{ { foo: 1 }, bar: 2 }" and this method returns " { foo: 1 }, bar: 2 " for last argument.
|
226
|
+
def stripped_old
|
227
|
+
return nil if old.nil?
|
228
|
+
old.sub!(/\A{/, '').sub!(/}\z/m, '')
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
207
232
|
# Processes and deals with lowering indentation.
|
208
233
|
def process_indent(line)
|
209
234
|
return unless line.tabs <= @template_tabs && @template_tabs > 0
|
@@ -396,22 +421,20 @@ module Haml
|
|
396
421
|
end
|
397
422
|
|
398
423
|
attributes = Parser.parse_class_and_id(attributes)
|
399
|
-
|
424
|
+
dynamic_attributes = DynamicAttributes.new
|
400
425
|
|
401
426
|
if attributes_hashes[:new]
|
402
427
|
static_attributes, attributes_hash = attributes_hashes[:new]
|
403
428
|
AttributeBuilder.merge_attributes!(attributes, static_attributes) if static_attributes
|
404
|
-
|
429
|
+
dynamic_attributes.new = attributes_hash
|
405
430
|
end
|
406
431
|
|
407
432
|
if attributes_hashes[:old]
|
408
433
|
static_attributes = parse_static_hash(attributes_hashes[:old])
|
409
434
|
AttributeBuilder.merge_attributes!(attributes, static_attributes) if static_attributes
|
410
|
-
|
435
|
+
dynamic_attributes.old = attributes_hashes[:old] unless static_attributes || @options.suppress_eval
|
411
436
|
end
|
412
437
|
|
413
|
-
attributes_list.compact!
|
414
|
-
|
415
438
|
raise SyntaxError.new(Error.message(:illegal_nesting_self_closing), @next_line.index) if block_opened? && self_closing
|
416
439
|
raise SyntaxError.new(Error.message(:no_ruby_code, action), last_line - 1) if parse && value.empty?
|
417
440
|
raise SyntaxError.new(Error.message(:self_closing_content), last_line - 1) if self_closing && !value.empty?
|
@@ -426,7 +449,7 @@ module Haml
|
|
426
449
|
line = handle_ruby_multiline(line) if parse
|
427
450
|
|
428
451
|
ParseNode.new(:tag, line.index + 1, :name => tag_name, :attributes => attributes,
|
429
|
-
:
|
452
|
+
:dynamic_attributes => dynamic_attributes, :self_closing => self_closing,
|
430
453
|
:nuke_inner_whitespace => nuke_inner_whitespace,
|
431
454
|
:nuke_outer_whitespace => nuke_outer_whitespace, :object_ref => object_ref,
|
432
455
|
:escape_html => escape_html, :preserve_tag => preserve_tag,
|
@@ -532,7 +555,7 @@ module Haml
|
|
532
555
|
attributes = {}
|
533
556
|
return attributes if list.empty?
|
534
557
|
|
535
|
-
list.scan(/([#.])([-:_a-zA-Z0-9]+)/) do |type, property|
|
558
|
+
list.scan(/([#.])([-:_a-zA-Z0-9\@]+)/) do |type, property|
|
536
559
|
case type
|
537
560
|
when '.'
|
538
561
|
if attributes[CLASS_KEY]
|
@@ -547,10 +570,16 @@ module Haml
|
|
547
570
|
attributes
|
548
571
|
end
|
549
572
|
|
573
|
+
# This method doesn't use Haml::AttributeParser because currently it depends on Ripper and Rubinius doesn't provide it.
|
574
|
+
# Ideally this logic should be placed in Haml::AttributeParser instead of here and this method should use it.
|
575
|
+
#
|
576
|
+
# @param [String] text - Hash literal or text inside old attributes
|
577
|
+
# @return [Hash,nil] - Return nil if text is not static Hash literal
|
550
578
|
def parse_static_hash(text)
|
551
579
|
attributes = {}
|
552
580
|
return attributes if text.empty?
|
553
581
|
|
582
|
+
text = text[1...-1] # strip brackets
|
554
583
|
scanner = StringScanner.new(text)
|
555
584
|
scanner.scan(/\s+/)
|
556
585
|
until scanner.eos?
|
@@ -565,7 +594,7 @@ module Haml
|
|
565
594
|
|
566
595
|
# Parses a line into tag_name, attributes, attributes_hash, object_ref, action, value
|
567
596
|
def parse_tag(text)
|
568
|
-
match = text.scan(/%([-:\w]+)([-:\w
|
597
|
+
match = text.scan(/%([-:\w]+)([-:\w.#\@]*)(.+)?/)[0]
|
569
598
|
raise SyntaxError.new(Error.message(:invalid_tag, text)) unless match
|
570
599
|
|
571
600
|
tag_name, attributes, rest = match
|
@@ -616,6 +645,9 @@ module Haml
|
|
616
645
|
nuke_inner_whitespace, action, value, last_line || @line.index + 1]
|
617
646
|
end
|
618
647
|
|
648
|
+
# @return [String] attributes_hash - Hash literal starting with `{` and ending with `}`
|
649
|
+
# @return [String] rest
|
650
|
+
# @return [Integer] last_line
|
619
651
|
def parse_old_attributes(text)
|
620
652
|
text = text.dup
|
621
653
|
last_line = @line.index + 1
|
@@ -633,10 +665,12 @@ module Haml
|
|
633
665
|
raise e
|
634
666
|
end
|
635
667
|
|
636
|
-
attributes_hash = attributes_hash[1...-1] if attributes_hash
|
637
668
|
return attributes_hash, rest, last_line
|
638
669
|
end
|
639
670
|
|
671
|
+
# @return [Array<Hash,String,nil>] - [static_attributs (Hash), dynamic_attributes (nil or String starting with `{` and ending with `}`)]
|
672
|
+
# @return [String] rest
|
673
|
+
# @return [Integer] last_line
|
640
674
|
def parse_new_attributes(text)
|
641
675
|
scanner = StringScanner.new(text)
|
642
676
|
last_line = @line.index + 1
|
data/lib/haml/plugin.rb
CHANGED
data/lib/haml/railtie.rb
CHANGED
@@ -1,35 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
if (activesupport_spec = Gem.loaded_specs['activesupport'])
|
4
|
-
if activesupport_spec.version.to_s < '3.2'
|
5
|
-
raise Exception.new("\n\n** Haml now requires Rails 3.2 and later. Use Haml version 4.0.4\n\n")
|
6
|
-
end
|
7
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'haml/template/options'
|
8
3
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
if defined? Erubi
|
14
|
-
require "haml/helpers/safe_erubi_template"
|
15
|
-
Haml::Filters::Erb.template_class = Haml::SafeErubiTemplate
|
16
|
-
else
|
17
|
-
require "haml/helpers/safe_erubis_template"
|
18
|
-
Haml::Filters::Erb.template_class = Haml::SafeErubisTemplate
|
19
|
-
end
|
4
|
+
# check for a compatible Rails version when Haml is loaded
|
5
|
+
if (activesupport_spec = Gem.loaded_specs['activesupport'])
|
6
|
+
if activesupport_spec.version.to_s < '3.2'
|
7
|
+
raise Exception.new("\n\n** Haml now requires Rails 3.2 and later. Use Haml version 4.0.4\n\n")
|
20
8
|
end
|
21
9
|
end
|
22
10
|
|
23
11
|
module Haml
|
24
12
|
class Railtie < ::Rails::Railtie
|
25
13
|
initializer :haml do |app|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
14
|
+
ActiveSupport.on_load(:action_view) do
|
15
|
+
require "haml/template"
|
16
|
+
|
17
|
+
if defined?(::Sass::Rails::SassTemplate) && app.config.assets.enabled
|
18
|
+
require "haml/sass_rails_filter"
|
19
|
+
end
|
20
|
+
|
21
|
+
if defined? Erubi
|
22
|
+
require "haml/helpers/safe_erubi_template"
|
23
|
+
Haml::Filters::Erb.template_class = Haml::SafeErubiTemplate
|
24
|
+
else
|
25
|
+
require "haml/helpers/safe_erubis_template"
|
26
|
+
Haml::Filters::Erb.template_class = Haml::SafeErubisTemplate
|
33
27
|
end
|
34
28
|
end
|
35
29
|
end
|
@@ -1,11 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module Haml
|
2
3
|
module Filters
|
3
4
|
# This is an extension of Sass::Rails's SassTemplate class that allows
|
4
5
|
# Rails's asset helpers to be used inside Haml Sass filter.
|
5
6
|
class SassRailsTemplate < ::Sass::Rails::SassTemplate
|
6
|
-
|
7
|
-
scope
|
8
|
-
|
7
|
+
if Gem::Version.new(Sprockets::VERSION) >= Gem::Version.new('3.0.0')
|
8
|
+
def render(scope=Object.new, locals={}, &block)
|
9
|
+
environment = ::Sprockets::Railtie.build_environment(Rails.application)
|
10
|
+
scope = environment.context_class.new(
|
11
|
+
environment: environment,
|
12
|
+
filename: "/",
|
13
|
+
metadata: {}
|
14
|
+
)
|
15
|
+
super
|
16
|
+
end
|
17
|
+
else
|
18
|
+
def render(scope=Object.new, locals={}, &block)
|
19
|
+
scope = ::Rails.application.assets.context_class.new(::Rails.application.assets, "/", "/")
|
20
|
+
super
|
21
|
+
end
|
9
22
|
end
|
10
23
|
|
11
24
|
def sass_options(scope)
|
@@ -30,4 +43,4 @@ module Haml
|
|
30
43
|
register_tilt_filter "Sass", :extend => "Css", :template_class => SassRailsTemplate
|
31
44
|
register_tilt_filter "Scss", :extend => "Css", :template_class => ScssRailsTemplate
|
32
45
|
end
|
33
|
-
end
|
46
|
+
end
|
data/lib/haml/template.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# We keep options in its own self-contained file
|
2
3
|
# so that we can load it independently in Rails 3,
|
3
4
|
# where the full template stuff is lazy-loaded.
|
@@ -6,11 +7,20 @@ module Haml
|
|
6
7
|
module Template
|
7
8
|
extend self
|
8
9
|
|
9
|
-
|
10
|
+
class Options < Hash
|
11
|
+
def []=(key, value)
|
12
|
+
super
|
13
|
+
if Haml::Options.buffer_defaults.key?(key)
|
14
|
+
Haml::Options.buffer_defaults[key] = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
@options = ::Haml::Template::Options.new
|
10
20
|
# The options hash for Haml when used within Rails.
|
11
21
|
# See {file:REFERENCE.md#options the Haml options documentation}.
|
12
22
|
#
|
13
|
-
# @return [
|
23
|
+
# @return [Haml::Template::Options<Symbol => Object>]
|
14
24
|
attr_accessor :options
|
15
25
|
end
|
16
26
|
end
|
data/lib/haml/temple_engine.rb
CHANGED
data/lib/haml/util.rb
CHANGED
data/lib/haml/version.rb
CHANGED
@@ -12,93 +12,89 @@ class AttributeParserTeset < Haml::TestCase
|
|
12
12
|
end
|
13
13
|
|
14
14
|
if Haml::AttributeParser.available?
|
15
|
-
it { assert_parse(
|
15
|
+
it { assert_parse(nil, '') }
|
16
16
|
it { assert_parse({}, '{}') }
|
17
17
|
|
18
18
|
describe 'invalid hash' do
|
19
|
-
it { assert_parse(nil, '
|
20
|
-
it { assert_parse(nil, 'hash, foo: bar') }
|
21
|
-
it { assert_parse(nil, ' {hash} ') }
|
22
|
-
it { assert_parse(nil, ' { hash, foo: bar } ') }
|
19
|
+
it { assert_parse(nil, '{hash}') }
|
20
|
+
it { assert_parse(nil, '{hash, foo: bar}') }
|
21
|
+
it { assert_parse(nil, '{ {hash} }') }
|
22
|
+
it { assert_parse(nil, '{ { hash, foo: bar } }') }
|
23
|
+
it { assert_parse(nil, '{}.merge({})') }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'non single hash' do
|
27
|
+
it { assert_parse(nil, '{ a: 0 };{}') }
|
28
|
+
it { assert_parse(nil, '{ a: 0 }[nil] = {}') }
|
23
29
|
end
|
24
30
|
|
25
31
|
describe 'dynamic key' do
|
26
|
-
it { assert_parse(nil, 'foo => bar') }
|
27
|
-
it { assert_parse(nil, '[] => bar') }
|
28
|
-
it { assert_parse(nil, '[1,2,3] => bar') }
|
32
|
+
it { assert_parse(nil, '{foo => bar}') }
|
33
|
+
it { assert_parse(nil, '{[] => bar}') }
|
34
|
+
it { assert_parse(nil, '{[1,2,3] => bar}') }
|
29
35
|
end
|
30
36
|
|
31
37
|
describe 'foo: bar' do
|
32
|
-
it { assert_parse({ '_' => '1' }, '_:1,') }
|
33
|
-
it { assert_parse({ 'foo' => 'bar' }, ' foo: bar ') }
|
34
|
-
it { assert_parse({ 'a' => 'b', 'c' => ':d' }, 'a: b, c: :d') }
|
35
|
-
it { assert_parse({ 'a' => '[]', 'c' => '"d"' }, 'a: [], c: "d"') }
|
36
|
-
it { assert_parse({ '_' => '1' }, ' { _:1, } ') }
|
37
|
-
it { assert_parse({ 'foo' => 'bar' }, ' { foo: bar } ') }
|
38
|
-
it { assert_parse({ 'a' => 'b', 'c' => ':d' }, ' { a: b, c: :d } ') }
|
39
|
-
it { assert_parse({ 'a' => '[]', 'c' => '"d"' }, ' { a: [], c: "d" } ') }
|
38
|
+
it { assert_parse({ '_' => '1' }, '{_:1,}') }
|
39
|
+
it { assert_parse({ 'foo' => 'bar' }, '{ foo: bar }') }
|
40
|
+
it { assert_parse({ 'a' => 'b', 'c' => ':d' }, '{a: b, c: :d}') }
|
41
|
+
it { assert_parse({ 'a' => '[]', 'c' => '"d"' }, '{a: [], c: "d"}') }
|
40
42
|
end
|
41
43
|
|
42
44
|
describe ':foo => bar' do
|
43
|
-
it { assert_parse({ 'foo' => ':bar' }, ' :foo => :bar ') }
|
44
|
-
it { assert_parse({ '_' => '"foo"' }, ':_=>"foo"') }
|
45
|
-
it { assert_parse({ 'a' => '[]', 'c' => '""', 'b' => '"#{3}"' }, ':a => [], c: "", :b => "#{3}"') }
|
46
|
-
it { assert_parse(
|
47
|
-
it { assert_parse(
|
48
|
-
it { assert_parse(
|
49
|
-
it { assert_parse(nil, ':"f#{o}o" => bar') }
|
50
|
-
it { assert_parse(nil, ':"#{f}oo" => bar') }
|
51
|
-
it { assert_parse(nil, ':"#{foo}" => bar') }
|
45
|
+
it { assert_parse({ 'foo' => ':bar' }, '{ :foo => :bar }') }
|
46
|
+
it { assert_parse({ '_' => '"foo"' }, '{:_=>"foo"}') }
|
47
|
+
it { assert_parse({ 'a' => '[]', 'c' => '""', 'b' => '"#{3}"' }, '{:a => [], c: "", :b => "#{3}"}') }
|
48
|
+
it { assert_parse(nil, '{:"f#{o}o" => bar}') }
|
49
|
+
it { assert_parse(nil, '{:"#{f}oo" => bar}') }
|
50
|
+
it { assert_parse(nil, '{:"#{foo}" => bar}') }
|
52
51
|
end
|
53
52
|
|
54
53
|
describe '"foo" => bar' do
|
55
|
-
it { assert_parse({ 'foo' => '[1]' }, '"foo"=>[1]') }
|
56
|
-
it { assert_parse({ 'foo' => 'nya' }, " 'foo' => nya ") }
|
57
|
-
it { assert_parse({ 'foo' => 'bar' }, '%q[foo] => bar ') }
|
54
|
+
it { assert_parse({ 'foo' => '[1]' }, '{"foo"=>[1]}') }
|
55
|
+
it { assert_parse({ 'foo' => 'nya' }, "{ 'foo' => nya }") }
|
56
|
+
it { assert_parse({ 'foo' => 'bar' }, '{%q[foo] => bar }') }
|
58
57
|
it { assert_parse({ 'foo' => '[1]' }, ' { "foo"=>[1] } ') }
|
59
58
|
it { assert_parse({ 'foo' => 'nya' }, " { 'foo' => nya } ") }
|
60
59
|
it { assert_parse({ 'foo' => 'bar' }, ' { %q[foo] => bar } ') }
|
61
|
-
it { assert_parse(nil, '"f#{o}o" => bar') }
|
62
|
-
it { assert_parse(nil, '"#{f}oo" => bar') }
|
63
|
-
it { assert_parse(nil, '"#{foo}" => bar') }
|
64
|
-
it { assert_parse({ 'f#{o}o' => 'bar' }, '%q[f#{o}o] => bar ') }
|
65
|
-
it { assert_parse({ 'f#{o}o' => 'bar' }, '
|
60
|
+
it { assert_parse(nil, '{"f#{o}o" => bar}') }
|
61
|
+
it { assert_parse(nil, '{"#{f}oo" => bar}') }
|
62
|
+
it { assert_parse(nil, '{"#{foo}" => bar}') }
|
63
|
+
it { assert_parse({ 'f#{o}o' => 'bar' }, '{ %q[f#{o}o] => bar }') }
|
64
|
+
it { assert_parse({ 'f#{o}o' => 'bar' }, '{ %q[f#{o}o] => bar, }') }
|
66
65
|
it { assert_parse(nil, '%Q[f#{o}o] => bar ') }
|
67
66
|
end
|
68
67
|
|
68
|
+
describe 'multi lines' do
|
69
|
+
it { assert_parse({ 'a' => 'b', 'c' => 'd' }, "{a: b,\nc: d}") }
|
70
|
+
end
|
71
|
+
|
69
72
|
if RUBY_VERSION >= '2.2.0'
|
70
73
|
describe '"foo": bar' do
|
71
|
-
it { assert_parse({ 'foo' => '()' }, '"foo":()') }
|
72
|
-
it { assert_parse({ 'foo' => 'nya' }, " 'foo': nya ") }
|
74
|
+
it { assert_parse({ 'foo' => '()' }, '{"foo":()}') }
|
75
|
+
it { assert_parse({ 'foo' => 'nya' }, " {'foo': nya} ") }
|
73
76
|
it { assert_parse({ 'foo' => '()' }, ' { "foo":() , }') }
|
74
77
|
it { assert_parse({ 'foo' => 'nya' }, " { 'foo': nya , }") }
|
75
|
-
it { assert_parse(nil, '"f#{o}o": bar') }
|
76
|
-
it { assert_parse(nil, '"#{f}oo": bar') }
|
77
|
-
it { assert_parse(nil, '"#{foo}": bar') }
|
78
|
+
it { assert_parse(nil, '{"f#{o}o": bar}') }
|
79
|
+
it { assert_parse(nil, '{"#{f}oo": bar}') }
|
80
|
+
it { assert_parse(nil, '{"#{foo}": bar}') }
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
81
84
|
describe 'nested array' do
|
82
|
-
it { assert_parse({ 'foo' => '[1,2,]' }, 'foo: [1,2,],') }
|
83
|
-
it { assert_parse({ 'foo' => '[1,2,[3,4],5]' }, 'foo: [1,2,[3,4],5],') }
|
84
|
-
it { assert_parse({ 'foo' => '[1,2,[3,4],5]', 'bar' => '[[1,2],]'}, 'foo: [1,2,[3,4],5],bar: [[1,2],],') }
|
85
|
-
it { assert_parse({ 'foo' => '[1,2,]' }, ' { foo: [1,2,], } ') }
|
86
|
-
it { assert_parse({ 'foo' => '[1,2,[3,4],5]' }, ' { foo: [1,2,[3,4],5], } ') }
|
87
|
-
it { assert_parse({ 'foo' => '[1,2,[3,4],5]', 'bar' => '[[1,2],]'}, ' { foo: [1,2,[3,4],5],bar: [[1,2],], } ') }
|
85
|
+
it { assert_parse({ 'foo' => '[1,2,]' }, '{foo: [1,2,],}') }
|
86
|
+
it { assert_parse({ 'foo' => '[1,2,[3,4],5]' }, '{foo: [1,2,[3,4],5],}') }
|
87
|
+
it { assert_parse({ 'foo' => '[1,2,[3,4],5]', 'bar' => '[[1,2],]'}, '{foo: [1,2,[3,4],5],bar: [[1,2],],}') }
|
88
88
|
end
|
89
89
|
|
90
90
|
describe 'nested hash' do
|
91
|
-
it { assert_parse({ 'foo' => '{ }', 'bar' => '{}' }, 'foo: { }, bar: {}') }
|
92
|
-
it { assert_parse({ 'foo' => '{ bar: baz, hoge: fuga, }' }, 'foo: { bar: baz, hoge: fuga, }, ') }
|
93
|
-
it { assert_parse({ 'data' => '{ confirm: true, disable: false }', 'hello' => '{ world: foo, }' }, 'data: { confirm: true, disable: false }, :hello => { world: foo, },') }
|
94
|
-
it { assert_parse({ 'foo' => '{ }', 'bar' => '{}' }, ' { foo: { }, bar: {} } ') }
|
95
|
-
it { assert_parse({ 'foo' => '{ bar: baz, hoge: fuga, }' }, ' { foo: { bar: baz, hoge: fuga, }, } ') }
|
96
|
-
it { assert_parse({ 'data' => '{ confirm: true, disable: false }', 'hello' => '{ world: foo, }' }, ' { data: { confirm: true, disable: false }, :hello => { world: foo, }, } ') }
|
91
|
+
it { assert_parse({ 'foo' => '{ }', 'bar' => '{}' }, '{foo: { }, bar: {}}') }
|
92
|
+
it { assert_parse({ 'foo' => '{ bar: baz, hoge: fuga, }' }, '{foo: { bar: baz, hoge: fuga, }, }') }
|
93
|
+
it { assert_parse({ 'data' => '{ confirm: true, disable: false }', 'hello' => '{ world: foo, }' }, '{data: { confirm: true, disable: false }, :hello => { world: foo, },}') }
|
97
94
|
end
|
98
95
|
|
99
96
|
describe 'nested method' do
|
100
|
-
it { assert_parse({ 'foo' => 'bar(a, b)', 'hoge' => 'piyo(a, b,)' }, 'foo: bar(a, b), hoge: piyo(a, b,),') }
|
101
|
-
it { assert_parse({ 'foo' => 'bar(a, b)', 'hoge' => 'piyo(a, b,)' }, ' { foo: bar(a, b), hoge: piyo(a, b,), } ') }
|
97
|
+
it { assert_parse({ 'foo' => 'bar(a, b)', 'hoge' => 'piyo(a, b,)' }, '{ foo: bar(a, b), hoge: piyo(a, b,), }') }
|
102
98
|
end
|
103
99
|
end
|
104
100
|
end
|
data/test/engine_test.rb
CHANGED
@@ -1555,6 +1555,12 @@ HAML
|
|
1555
1555
|
HAML
|
1556
1556
|
end
|
1557
1557
|
|
1558
|
+
def test_hash_method_call_in_attributes
|
1559
|
+
assert_equal(%Q{<a foo='bar' hoge='fuga'></a>\n}, render(<<-HAML))
|
1560
|
+
- hash = {:hoge => :fuga}
|
1561
|
+
%a{{foo: 'bar'}.merge(hash)}
|
1562
|
+
HAML
|
1563
|
+
end
|
1558
1564
|
|
1559
1565
|
def test_html5_data_attributes_with_nested_hash
|
1560
1566
|
assert_equal("<div data-a-b='c'></div>\n", render(<<-HAML))
|
data/test/options_test.rb
CHANGED
@@ -9,11 +9,12 @@ module Haml
|
|
9
9
|
)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def test_buffer_defaults_values_are_the_same_as_rails_defaults
|
13
|
+
rails_defaults = Haml::Options.defaults.merge(Haml::Template.options)
|
13
14
|
Haml::Options.buffer_option_keys.each do |key|
|
14
15
|
assert_equal(
|
15
|
-
|
16
|
-
Haml::Options.buffer_defaults[key],
|
16
|
+
rails_defaults[key],
|
17
|
+
Haml::Options.buffer_defaults[key], "key: #{key}"
|
17
18
|
)
|
18
19
|
end
|
19
20
|
end
|
data/test/template_test.rb
CHANGED
@@ -8,7 +8,7 @@ class TemplateTest < Haml::TestCase
|
|
8
8
|
TEMPLATES = %w{ very_basic standard helpers
|
9
9
|
whitespace_handling original_engine list helpful
|
10
10
|
silent_script tag_parsing just_stuff partials
|
11
|
-
nuke_outer_whitespace nuke_inner_whitespace
|
11
|
+
nuke_outer_whitespace nuke_inner_whitespace bemit
|
12
12
|
render_layout partial_layout partial_layout_erb}
|
13
13
|
|
14
14
|
def setup
|
data/test/test_helper.rb
CHANGED
@@ -26,6 +26,7 @@ if defined?(I18n.enforce_available_locales)
|
|
26
26
|
end
|
27
27
|
|
28
28
|
class TestApp < Rails::Application
|
29
|
+
config.eager_load = false
|
29
30
|
config.root = ""
|
30
31
|
end
|
31
32
|
Rails.application = TestApp
|
@@ -39,6 +40,8 @@ $VERBOSE = true
|
|
39
40
|
require 'haml'
|
40
41
|
require 'haml/template'
|
41
42
|
|
43
|
+
TestApp.initialize!
|
44
|
+
|
42
45
|
Haml::Template.options[:format] = :xhtml
|
43
46
|
|
44
47
|
BASE_TEST_CLASS = if defined?(Minitest::Test)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Natalie Weizenbaum
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-
|
14
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: temple
|
@@ -166,6 +166,7 @@ files:
|
|
166
166
|
- test/mocks/article.rb
|
167
167
|
- test/options_test.rb
|
168
168
|
- test/parser_test.rb
|
169
|
+
- test/results/bemit.xhtml
|
169
170
|
- test/results/content_for_layout.xhtml
|
170
171
|
- test/results/eval_suppressed.xhtml
|
171
172
|
- test/results/helpers.xhtml
|
@@ -194,6 +195,7 @@ files:
|
|
194
195
|
- test/templates/_text_area.haml
|
195
196
|
- test/templates/_text_area_helper.html.haml
|
196
197
|
- test/templates/action_view.haml
|
198
|
+
- test/templates/bemit.haml
|
197
199
|
- test/templates/breakage.haml
|
198
200
|
- test/templates/content_for_layout.haml
|
199
201
|
- test/templates/eval_suppressed.haml
|
@@ -234,12 +236,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
234
236
|
version: 2.0.0
|
235
237
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
236
238
|
requirements:
|
237
|
-
- - "
|
239
|
+
- - ">="
|
238
240
|
- !ruby/object:Gem::Version
|
239
|
-
version:
|
241
|
+
version: '0'
|
240
242
|
requirements: []
|
241
243
|
rubyforge_project:
|
242
|
-
rubygems_version: 2.6.
|
244
|
+
rubygems_version: 2.6.11
|
243
245
|
signing_key:
|
244
246
|
specification_version: 4
|
245
247
|
summary: An elegant, structured (X)HTML/XML templating engine.
|