faml 0.5.0 → 0.5.1
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 +4 -0
- data/ext/attribute_builder/attribute_builder.c +22 -12
- data/incompatibilities/README.md +1 -1
- data/incompatibilities/spec/render/attribute_spec.md +18 -0
- data/lib/faml/attribute_compiler.rb +98 -0
- data/lib/faml/attribute_optimizer.rb +100 -0
- data/lib/faml/compiler.rb +2 -169
- data/lib/faml/error.rb +3 -0
- data/lib/faml/version.rb +1 -1
- data/spec/rails/spec/requests/faml_spec.rb +1 -1
- data/spec/render/attribute_spec.rb +5 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 467a84dc8e9b891942ce31fc121c273080fcc72a
|
|
4
|
+
data.tar.gz: 9523d713adcd1dc6daf5dd384cf74fc26e5be883
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a2f64b49c6b59166fc97eab6078a4a0e529ed9c0b9fa45257891606c0c49582b100d08fd64e38e5ef0bf9c2aa689e79888db4381ddc5ce119268163f6c647c9f
|
|
7
|
+
data.tar.gz: 9ddc8674331446ae2459eeeb0360f924d383f88b2cbdef065a47a765f420d3ae9e6ebee590ca241db3e3ae02a958903082818eb38700d7872ed5c792bd894d42
|
data/CHANGELOG.md
CHANGED
|
@@ -165,19 +165,28 @@ normalize(VALUE hash)
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
static void
|
|
168
|
-
|
|
168
|
+
merge_one(VALUE attributes, VALUE arg)
|
|
169
|
+
{
|
|
170
|
+
VALUE h;
|
|
171
|
+
|
|
172
|
+
Check_Type(arg, T_HASH);
|
|
173
|
+
h = stringify_keys(arg);
|
|
174
|
+
concat_array_attribute(attributes, h, rb_const_get(rb_mAttributeBuilder, id_class));
|
|
175
|
+
concat_array_attribute(attributes, h, rb_const_get(rb_mAttributeBuilder, id_id));
|
|
176
|
+
normalize(h);
|
|
177
|
+
rb_funcall(attributes, id_merge_bang, 1, h);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
static void
|
|
181
|
+
merge(VALUE attributes, VALUE object_ref, int argc, VALUE *argv)
|
|
169
182
|
{
|
|
170
183
|
int i;
|
|
171
184
|
|
|
172
185
|
for (i = 0; i < argc; i++) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
concat_array_attribute(attributes, h, rb_const_get(rb_mAttributeBuilder, id_class));
|
|
178
|
-
concat_array_attribute(attributes, h, rb_const_get(rb_mAttributeBuilder, id_id));
|
|
179
|
-
normalize(h);
|
|
180
|
-
rb_funcall(attributes, id_merge_bang, 1, h);
|
|
186
|
+
merge_one(attributes, argv[i]);
|
|
187
|
+
}
|
|
188
|
+
if (!NIL_P(object_ref)) {
|
|
189
|
+
merge_one(attributes, object_ref);
|
|
181
190
|
}
|
|
182
191
|
}
|
|
183
192
|
|
|
@@ -253,17 +262,18 @@ build_attribute(VALUE buf, VALUE attr_quote, int is_html, VALUE key, VALUE value
|
|
|
253
262
|
static VALUE
|
|
254
263
|
m_build(int argc, VALUE *argv, RB_UNUSED_VAR(VALUE self))
|
|
255
264
|
{
|
|
256
|
-
VALUE attr_quote, attributes, keys, buf;
|
|
265
|
+
VALUE attr_quote, object_ref, attributes, keys, buf;
|
|
257
266
|
int is_html;
|
|
258
267
|
long len, i;
|
|
259
268
|
|
|
260
|
-
rb_check_arity(argc,
|
|
269
|
+
rb_check_arity(argc, 3, UNLIMITED_ARGUMENTS);
|
|
261
270
|
attr_quote = argv[0];
|
|
262
271
|
is_html = RTEST(argv[1]);
|
|
272
|
+
object_ref = argv[2];
|
|
263
273
|
attributes = rb_hash_new();
|
|
264
274
|
rb_hash_aset(attributes, rb_const_get(rb_mAttributeBuilder, id_id), rb_ary_new());
|
|
265
275
|
rb_hash_aset(attributes, rb_const_get(rb_mAttributeBuilder, id_class), rb_ary_new());
|
|
266
|
-
merge(attributes, argc-
|
|
276
|
+
merge(attributes, object_ref, argc-3, argv+3);
|
|
267
277
|
|
|
268
278
|
keys = rb_funcall(attributes, id_keys, 0);
|
|
269
279
|
rb_funcall(keys, id_sort_bang, 0);
|
data/incompatibilities/README.md
CHANGED
|
@@ -513,3 +513,21 @@
|
|
|
513
513
|
|
|
514
514
|
```
|
|
515
515
|
|
|
516
|
+
# [./spec/render/attribute_spec.rb:227](../../../spec/render/attribute_spec.rb#L227)
|
|
517
|
+
## Input
|
|
518
|
+
```haml
|
|
519
|
+
%span#baz[Faml::TestStruct.new(123)]{id: "foo"} hello
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
## Faml, Haml
|
|
523
|
+
```html
|
|
524
|
+
<span class='faml_test_struct' id='baz_foo_faml_test_struct_123'>hello</span>
|
|
525
|
+
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
## Hamlit
|
|
529
|
+
```html
|
|
530
|
+
<span id='baz'>[Faml::TestStruct.new(123)]{id: "foo"} hello</span>
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require_relative 'attribute_optimizer'
|
|
2
|
+
require_relative 'object_ref'
|
|
3
|
+
|
|
4
|
+
module Faml
|
|
5
|
+
class AttributeCompiler
|
|
6
|
+
def compile(ast)
|
|
7
|
+
if !ast.object_ref && ast.attributes.empty?
|
|
8
|
+
return compile_static_id_and_class(ast.static_id, ast.static_class)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
unless ast.object_ref
|
|
12
|
+
attrs = try_optimize_attributes(ast.attributes, ast.static_id, ast.static_class)
|
|
13
|
+
if attrs
|
|
14
|
+
line_count = ast.attributes.count("\n")
|
|
15
|
+
return [:multi, [:html, :attrs, *attrs]].concat([[:newline]] * line_count)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
compile_slow_attributes(ast.attributes, ast.static_id, ast.static_class, ast.object_ref)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def compile_static_id_and_class(static_id, static_class)
|
|
25
|
+
[:html, :attrs].tap do |html_attrs|
|
|
26
|
+
unless static_class.empty?
|
|
27
|
+
html_attrs << [:haml, :attr, 'class', [:static, static_class]]
|
|
28
|
+
end
|
|
29
|
+
unless static_id.empty?
|
|
30
|
+
html_attrs << [:haml, :attr, 'id', [:static, static_id]]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def try_optimize_attributes(text, static_id, static_class)
|
|
36
|
+
static_attributes, dynamic_attributes = AttributeOptimizer.new.try_optimize(text, static_id, static_class)
|
|
37
|
+
if static_attributes
|
|
38
|
+
(static_attributes.keys + dynamic_attributes.keys).sort.flat_map do |k|
|
|
39
|
+
if static_attributes.key?(k)
|
|
40
|
+
compile_static_attribute(k, static_attributes[k])
|
|
41
|
+
else
|
|
42
|
+
compile_dynamic_attribute(k, dynamic_attributes[k])
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def compile_static_attribute(key, value)
|
|
49
|
+
if value.is_a?(Hash) && key == 'data'
|
|
50
|
+
data = AttributeBuilder.normalize_data(value)
|
|
51
|
+
data.keys.sort.map do |k|
|
|
52
|
+
compile_static_simple_attribute("data-#{k}", data[k])
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
[compile_static_simple_attribute(key, value)]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def compile_static_simple_attribute(key, value)
|
|
60
|
+
case
|
|
61
|
+
when value == true
|
|
62
|
+
[:haml, :attr, key, [:multi]]
|
|
63
|
+
when value == false || value.nil?
|
|
64
|
+
[:multi]
|
|
65
|
+
else
|
|
66
|
+
[:haml, :attr, key, [:static, Temple::Utils.escape_html(value)]]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def compile_dynamic_attribute(key, value)
|
|
71
|
+
[[:haml, :attr, key, [:dvalue, value]]]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def compile_slow_attributes(text, static_id, static_class, object_ref)
|
|
75
|
+
h = {}
|
|
76
|
+
unless static_class.empty?
|
|
77
|
+
h[:class] = static_class.split(/ +/)
|
|
78
|
+
end
|
|
79
|
+
unless static_id.empty?
|
|
80
|
+
h[:id] = static_id
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
codes = []
|
|
84
|
+
if object_ref
|
|
85
|
+
codes << "::Faml::ObjectRef.render(#{object_ref})"
|
|
86
|
+
else
|
|
87
|
+
codes << 'nil'
|
|
88
|
+
end
|
|
89
|
+
unless h.empty?
|
|
90
|
+
codes << h.inspect
|
|
91
|
+
end
|
|
92
|
+
unless text.empty?
|
|
93
|
+
codes << text
|
|
94
|
+
end
|
|
95
|
+
[:haml, :attrs, codes.join(', ')]
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require_relative 'error'
|
|
2
|
+
require_relative 'ruby_syntax_checker'
|
|
3
|
+
require_relative 'static_hash_parser'
|
|
4
|
+
|
|
5
|
+
module Faml
|
|
6
|
+
class AttributeOptimizer
|
|
7
|
+
def try_optimize(text, static_id, static_class)
|
|
8
|
+
parser = StaticHashParser.new
|
|
9
|
+
unless parser.parse("{#{text}}")
|
|
10
|
+
assert_valid_ruby_code!(text)
|
|
11
|
+
return [nil, nil]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
static_attributes, dynamic_attributes = build_optimized_attributes(parser, static_id, static_class)
|
|
15
|
+
if optimizable?(text, static_attributes, dynamic_attributes)
|
|
16
|
+
[static_attributes, dynamic_attributes]
|
|
17
|
+
else
|
|
18
|
+
[nil, nil]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def assert_valid_ruby_code!(text)
|
|
25
|
+
RubySyntaxChecker.new("call(#{text})", '(faml)').parse
|
|
26
|
+
true
|
|
27
|
+
rescue RubySyntaxChecker::Error
|
|
28
|
+
raise UnparsableRubyCode.new("Unparsable Ruby code is given to attributes: #{text}", nil)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def build_optimized_attributes(parser, static_id, static_class)
|
|
32
|
+
static_attributes = build_optimized_static_attributes(parser, static_id, static_class)
|
|
33
|
+
dynamic_attributes = build_optimized_dynamic_attributes(parser, static_attributes)
|
|
34
|
+
if dynamic_attributes
|
|
35
|
+
[static_attributes, dynamic_attributes]
|
|
36
|
+
else
|
|
37
|
+
[nil, nil]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def build_optimized_static_attributes(parser, static_id, static_class)
|
|
42
|
+
static_attributes = {}
|
|
43
|
+
parser.static_attributes.each do |k, v|
|
|
44
|
+
static_attributes[k.to_s] = v
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class_list = Array(static_attributes.delete('class')).select { |v| v }.flat_map { |c| c.to_s.split(/ +/) }
|
|
48
|
+
unless static_class.empty?
|
|
49
|
+
class_list.concat(static_class.split(/ +/))
|
|
50
|
+
end
|
|
51
|
+
unless class_list.empty?
|
|
52
|
+
static_attributes['class'] = class_list.uniq.sort.join(' ')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
id_list = Array(static_attributes.delete('id')).select { |v| v }
|
|
56
|
+
unless static_id.empty?
|
|
57
|
+
id_list = [static_id].concat(id_list)
|
|
58
|
+
end
|
|
59
|
+
unless id_list.empty?
|
|
60
|
+
static_attributes['id'] = id_list.join('_')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
static_attributes
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def build_optimized_dynamic_attributes(parser, static_attributes)
|
|
67
|
+
dynamic_attributes = {}
|
|
68
|
+
parser.dynamic_attributes.each do |k, v|
|
|
69
|
+
k = k.to_s
|
|
70
|
+
if static_attributes.key?(k)
|
|
71
|
+
if StaticHashParser::SPECIAL_ATTRIBUTES.include?(k)
|
|
72
|
+
# XXX: Quit optimization
|
|
73
|
+
return nil
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
dynamic_attributes[k] = v
|
|
77
|
+
end
|
|
78
|
+
dynamic_attributes
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def optimizable?(text, static_attributes, dynamic_attributes)
|
|
82
|
+
if static_attributes.nil?
|
|
83
|
+
return false
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if dynamic_attributes.key?('data')
|
|
87
|
+
# XXX: Quit optimization...
|
|
88
|
+
return false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if text.include?("\n") && !dynamic_attributes.empty?
|
|
92
|
+
# XXX: Quit optimization to keep newlines
|
|
93
|
+
# https://github.com/eagletmt/faml/issues/18
|
|
94
|
+
return false
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
true
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
data/lib/faml/compiler.rb
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
require 'ripper'
|
|
2
2
|
require 'temple'
|
|
3
3
|
require 'haml_parser/ast'
|
|
4
|
+
require_relative 'attribute_compiler'
|
|
4
5
|
require_relative 'error'
|
|
5
6
|
require_relative 'filter_compilers'
|
|
6
7
|
require_relative 'helpers'
|
|
7
|
-
require_relative 'object_ref'
|
|
8
8
|
require_relative 'rails_helpers'
|
|
9
|
-
require_relative 'ruby_syntax_checker'
|
|
10
|
-
require_relative 'static_hash_parser'
|
|
11
9
|
require_relative 'text_compiler'
|
|
12
10
|
|
|
13
11
|
module Faml
|
|
14
12
|
class Compiler < Temple::Parser
|
|
15
|
-
class UnparsableRubyCode < Error
|
|
16
|
-
end
|
|
17
|
-
|
|
18
13
|
DEFAULT_AUTO_CLOSE_TAGS = %w[
|
|
19
14
|
area base basefont br col command embed frame hr img input isindex keygen
|
|
20
15
|
link menuitem meta param source track wbr
|
|
@@ -182,7 +177,7 @@ module Faml
|
|
|
182
177
|
:haml, :tag,
|
|
183
178
|
ast.tag_name,
|
|
184
179
|
self_closing?(ast),
|
|
185
|
-
|
|
180
|
+
AttributeCompiler.new.compile(ast),
|
|
186
181
|
]
|
|
187
182
|
|
|
188
183
|
if ast.oneline_child
|
|
@@ -224,168 +219,6 @@ module Faml
|
|
|
224
219
|
ast.nuke_inner_whitespace || options[:preserve].include?(ast.tag_name)
|
|
225
220
|
end
|
|
226
221
|
|
|
227
|
-
def compile_attributes(text, static_id, static_class, object_ref)
|
|
228
|
-
if !object_ref && text.empty?
|
|
229
|
-
return compile_static_id_and_class(static_id, static_class)
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
unless object_ref
|
|
233
|
-
attrs = try_optimize_attributes(text, static_id, static_class)
|
|
234
|
-
if attrs
|
|
235
|
-
line_count = text.count("\n")
|
|
236
|
-
return [:multi, [:html, :attrs, *attrs]].concat([[:newline]] * line_count)
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
# Slow version
|
|
241
|
-
|
|
242
|
-
h = {}
|
|
243
|
-
unless static_class.empty?
|
|
244
|
-
h[:class] = static_class.split(/ +/)
|
|
245
|
-
end
|
|
246
|
-
unless static_id.empty?
|
|
247
|
-
h[:id] = static_id
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
codes = []
|
|
251
|
-
unless h.empty?
|
|
252
|
-
codes << h.inspect
|
|
253
|
-
end
|
|
254
|
-
if object_ref
|
|
255
|
-
codes << "::Faml::ObjectRef.render(#{object_ref})"
|
|
256
|
-
end
|
|
257
|
-
unless text.empty?
|
|
258
|
-
codes << text
|
|
259
|
-
end
|
|
260
|
-
[:haml, :attrs, codes.join(', ')]
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def compile_static_id_and_class(static_id, static_class)
|
|
264
|
-
[:html, :attrs].tap do |html_attrs|
|
|
265
|
-
unless static_class.empty?
|
|
266
|
-
html_attrs << [:haml, :attr, 'class', [:static, static_class]]
|
|
267
|
-
end
|
|
268
|
-
unless static_id.empty?
|
|
269
|
-
html_attrs << [:haml, :attr, 'id', [:static, static_id]]
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def try_optimize_attributes(text, static_id, static_class)
|
|
275
|
-
parser = StaticHashParser.new
|
|
276
|
-
unless parser.parse("{#{text}}")
|
|
277
|
-
assert_valid_ruby_code!(text)
|
|
278
|
-
return nil
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
static_attributes, dynamic_attributes = build_optimized_attributes(parser, static_id, static_class)
|
|
282
|
-
if static_attributes.nil?
|
|
283
|
-
return nil
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
if dynamic_attributes.key?('data')
|
|
287
|
-
# XXX: Quit optimization...
|
|
288
|
-
return nil
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
if text.include?("\n") && !dynamic_attributes.empty?
|
|
292
|
-
# XXX: Quit optimization to keep newlines
|
|
293
|
-
# https://github.com/eagletmt/faml/issues/18
|
|
294
|
-
return nil
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
(static_attributes.keys + dynamic_attributes.keys).sort.flat_map do |k|
|
|
298
|
-
if static_attributes.key?(k)
|
|
299
|
-
compile_static_attribute(k, static_attributes[k])
|
|
300
|
-
else
|
|
301
|
-
compile_dynamic_attribute(k, dynamic_attributes[k])
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
def assert_valid_ruby_code!(text)
|
|
307
|
-
RubySyntaxChecker.new("call(#{text})", '(faml)').parse
|
|
308
|
-
true
|
|
309
|
-
rescue RubySyntaxChecker::Error
|
|
310
|
-
raise UnparsableRubyCode.new("Unparsable Ruby code is given to attributes: #{text}", nil)
|
|
311
|
-
end
|
|
312
|
-
|
|
313
|
-
def build_optimized_attributes(parser, static_id, static_class)
|
|
314
|
-
static_attributes = build_optimized_static_attributes(parser, static_id, static_class)
|
|
315
|
-
dynamic_attributes = build_optimized_dynamic_attributes(parser, static_attributes)
|
|
316
|
-
if dynamic_attributes
|
|
317
|
-
[static_attributes, dynamic_attributes]
|
|
318
|
-
else
|
|
319
|
-
[nil, nil]
|
|
320
|
-
end
|
|
321
|
-
end
|
|
322
|
-
|
|
323
|
-
def build_optimized_static_attributes(parser, static_id, static_class)
|
|
324
|
-
static_attributes = {}
|
|
325
|
-
parser.static_attributes.each do |k, v|
|
|
326
|
-
static_attributes[k.to_s] = v
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
class_list = Array(static_attributes.delete('class')).select { |v| v }.flat_map { |c| c.to_s.split(/ +/) }
|
|
330
|
-
unless static_class.empty?
|
|
331
|
-
class_list.concat(static_class.split(/ +/))
|
|
332
|
-
end
|
|
333
|
-
unless class_list.empty?
|
|
334
|
-
static_attributes['class'] = class_list.uniq.sort.join(' ')
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
id_list = Array(static_attributes.delete('id')).select { |v| v }
|
|
338
|
-
unless static_id.empty?
|
|
339
|
-
id_list = [static_id].concat(id_list)
|
|
340
|
-
end
|
|
341
|
-
unless id_list.empty?
|
|
342
|
-
static_attributes['id'] = id_list.join('_')
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
static_attributes
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
def build_optimized_dynamic_attributes(parser, static_attributes)
|
|
349
|
-
dynamic_attributes = {}
|
|
350
|
-
parser.dynamic_attributes.each do |k, v|
|
|
351
|
-
k = k.to_s
|
|
352
|
-
if static_attributes.key?(k)
|
|
353
|
-
if StaticHashParser::SPECIAL_ATTRIBUTES.include?(k)
|
|
354
|
-
# XXX: Quit optimization
|
|
355
|
-
return nil
|
|
356
|
-
end
|
|
357
|
-
end
|
|
358
|
-
dynamic_attributes[k] = v
|
|
359
|
-
end
|
|
360
|
-
dynamic_attributes
|
|
361
|
-
end
|
|
362
|
-
|
|
363
|
-
def compile_static_attribute(key, value)
|
|
364
|
-
if value.is_a?(Hash) && key == 'data'
|
|
365
|
-
data = AttributeBuilder.normalize_data(value)
|
|
366
|
-
data.keys.sort.map do |k|
|
|
367
|
-
compile_static_simple_attribute("data-#{k}", data[k])
|
|
368
|
-
end
|
|
369
|
-
else
|
|
370
|
-
[compile_static_simple_attribute(key, value)]
|
|
371
|
-
end
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
def compile_static_simple_attribute(key, value)
|
|
375
|
-
case
|
|
376
|
-
when value == true
|
|
377
|
-
[:haml, :attr, key, [:multi]]
|
|
378
|
-
when value == false || value.nil?
|
|
379
|
-
[:multi]
|
|
380
|
-
else
|
|
381
|
-
[:haml, :attr, key, [:static, Temple::Utils.escape_html(value)]]
|
|
382
|
-
end
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
def compile_dynamic_attribute(key, value)
|
|
386
|
-
[[:haml, :attr, key, [:dvalue, value]]]
|
|
387
|
-
end
|
|
388
|
-
|
|
389
222
|
def compile_script(ast)
|
|
390
223
|
sym = unique_name
|
|
391
224
|
temple = [:multi]
|
data/lib/faml/error.rb
CHANGED
data/lib/faml/version.rb
CHANGED
|
@@ -84,7 +84,7 @@ RSpec.describe 'Faml with Rails', type: :request do
|
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
describe Faml::
|
|
87
|
+
describe Faml::UnparsableRubyCode do
|
|
88
88
|
it 'has proper backtrace' do
|
|
89
89
|
expect { get '/books/unparsable' }.to raise_error { |e|
|
|
90
90
|
expect(e.backtrace[0]).to end_with('app/views/books/unparsable.html.haml:2')
|
|
@@ -102,7 +102,7 @@ HAML
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
it 'raises error when unparsable Ruby code is given' do
|
|
105
|
-
expect { render_string('%span{x ==== 2}') }.to raise_error(Faml::
|
|
105
|
+
expect { render_string('%span{x ==== 2}') }.to raise_error(Faml::UnparsableRubyCode)
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
context 'with xhtml format' do
|
|
@@ -223,5 +223,9 @@ HAML
|
|
|
223
223
|
it 'renders id and class attribute with haml_object_ref' do
|
|
224
224
|
expect(render_string('%span[Faml::TestRefStruct.new(123)] hello')).to eq("<span class='faml_test' id='faml_test_123'>hello</span>\n")
|
|
225
225
|
end
|
|
226
|
+
|
|
227
|
+
it 'renders id in correct order' do
|
|
228
|
+
expect(render_string('%span#baz[Faml::TestStruct.new(123)]{id: "foo"} hello')).to eq("<span class='faml_test_struct' id='baz_foo_faml_test_struct_123'>hello</span>\n")
|
|
229
|
+
end
|
|
226
230
|
end
|
|
227
231
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: faml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kohei Suzuki
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-11-
|
|
11
|
+
date: 2015-11-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: escape_utils
|
|
@@ -350,6 +350,8 @@ files:
|
|
|
350
350
|
- incompatibilities/spec/render/silent_script_spec.md
|
|
351
351
|
- incompatibilities/spec/render/unescape_spec.md
|
|
352
352
|
- lib/faml.rb
|
|
353
|
+
- lib/faml/attribute_compiler.rb
|
|
354
|
+
- lib/faml/attribute_optimizer.rb
|
|
353
355
|
- lib/faml/cli.rb
|
|
354
356
|
- lib/faml/compiler.rb
|
|
355
357
|
- lib/faml/engine.rb
|