rblade 0.4.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -1
- data/README.md +115 -517
- data/lib/rblade/compiler/compiles_components.rb +29 -11
- data/lib/rblade/compiler/compiles_echos.rb +4 -4
- data/lib/rblade/compiler/compiles_ruby.rb +1 -1
- data/lib/rblade/compiler/compiles_statements.rb +21 -13
- data/lib/rblade/compiler/statements/compiles_conditionals.rb +40 -0
- data/lib/rblade/compiler/statements/compiles_form.rb +48 -0
- data/lib/rblade/compiler/statements/compiles_props.rb +23 -4
- data/lib/rblade/compiler/statements/compiles_stacks.rb +39 -15
- data/lib/rblade/compiler/tokenizes_statements.rb +13 -2
- data/lib/rblade/compiler.rb +9 -0
- data/lib/rblade/component_store.rb +1 -1
- data/lib/rblade/helpers/attributes_manager.rb +37 -7
- data/lib/rblade/helpers/html_string.rb +4 -0
- data/lib/rblade/helpers/slot_manager.rb +31 -0
- data/lib/rblade/helpers/stack_manager.rb +4 -0
- data/lib/rblade/rails_template.rb +1 -0
- data/rblade.gemspec +1 -1
- metadata +9 -7
- data/TODO.md +0 -2
@@ -26,17 +26,16 @@ module RBlade
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def compile_token_start token
|
29
|
-
|
30
|
-
|
31
|
-
@component_stack << {
|
29
|
+
component = {
|
32
30
|
name: token.value[:name],
|
33
|
-
index: @
|
31
|
+
index: @component_stack.count
|
34
32
|
}
|
33
|
+
@component_stack << component
|
35
34
|
|
36
35
|
attributes = compile_attributes token.value[:attributes]
|
37
36
|
|
38
|
-
code = "_c#{
|
39
|
-
code << "_c#{
|
37
|
+
code = "_c#{component[:index]}_swap=_out;_out='';"
|
38
|
+
code << "_c#{component[:index]}_attr={#{attributes.join(",")}};"
|
40
39
|
|
41
40
|
code
|
42
41
|
end
|
@@ -50,15 +49,34 @@ module RBlade
|
|
50
49
|
raise StandardError.new "Unexpected closing tag (#{token.value[:name]}) expecting #{component[:name]}"
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
namespace = nil
|
53
|
+
name = component[:name]
|
54
|
+
if name.match '::'
|
55
|
+
namespace, name = component[:name].split("::")
|
56
|
+
end
|
57
|
+
|
58
|
+
code = if namespace == 'slot'
|
59
|
+
compile_slot_end name, component
|
60
|
+
else
|
61
|
+
compile_component_end component
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def compile_slot_end name, component
|
66
|
+
parent = @component_stack.last
|
67
|
+
|
68
|
+
code = "_c#{parent[:index]}_attr[:'#{RBlade.escape_quotes(name)}']=RBlade::SlotManager.new(_out,_c#{component[:index]}_attr);"
|
69
|
+
code << "_out=_c#{component[:index]}_swap;_c#{component[:index]}_swap=nil;_c#{component[:index]}_attr=nil;"
|
56
70
|
|
57
71
|
code
|
58
72
|
end
|
59
73
|
|
60
|
-
def
|
61
|
-
|
74
|
+
def compile_component_end component
|
75
|
+
code = "_slot=RBlade::SlotManager.new(_out);_out=_c#{component[:index]}_swap;"
|
76
|
+
code << "_out<<#{ComponentStore.component(component[:name])}(_slot,_c#{component[:index]}_attr,params,session,flash,cookies);"
|
77
|
+
code << "_slot=nil;_c#{component[:index]}_swap=nil;_c#{component[:index]}_attr=nil;"
|
78
|
+
|
79
|
+
code
|
62
80
|
end
|
63
81
|
|
64
82
|
def compile_attributes attributes
|
@@ -8,8 +8,8 @@ module RBlade
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def compile_regular_echos!(tokens)
|
11
|
-
compile_echos! tokens, "{{", "}}", "
|
12
|
-
compile_echos! tokens, "<%=", "%>", "
|
11
|
+
compile_echos! tokens, "{{", "}}", "RBlade.e"
|
12
|
+
compile_echos! tokens, "<%=", "%>", "RBlade.e"
|
13
13
|
end
|
14
14
|
|
15
15
|
def compile_unsafe_echos!(tokens)
|
@@ -35,8 +35,8 @@ module RBlade
|
|
35
35
|
segments.delete_at i
|
36
36
|
segments.delete_at i + 1
|
37
37
|
segment_value = "_out<<"
|
38
|
-
|
39
|
-
segment_value <<= if !wrapper_function.nil?
|
38
|
+
|
39
|
+
segment_value <<= if !wrapper_function.nil?
|
40
40
|
wrapper_function + "(" + segments[i] + ");"
|
41
41
|
else
|
42
42
|
"(" + segments[i] + ").to_s;"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "rblade/compiler/statements/compiles_conditionals"
|
2
|
+
require "rblade/compiler/statements/compiles_form"
|
2
3
|
require "rblade/compiler/statements/compiles_html_attributes"
|
3
4
|
require "rblade/compiler/statements/compiles_inline_ruby"
|
4
5
|
require "rblade/compiler/statements/compiles_loops"
|
@@ -48,7 +49,12 @@ module RBlade
|
|
48
49
|
handler_class, handler_method = @@statement_handlers[name.tr("_", "").downcase]
|
49
50
|
|
50
51
|
if !handler_class&.method_defined?(handler_method)
|
51
|
-
|
52
|
+
if name.start_with? "end"
|
53
|
+
## Fallback to the default end handler
|
54
|
+
handler_class, handler_method = @@statement_handlers["end"]
|
55
|
+
else
|
56
|
+
raise StandardError.new "Unhandled statement: @#{name}"
|
57
|
+
end
|
52
58
|
end
|
53
59
|
|
54
60
|
if handler_class == CompilesStatements
|
@@ -63,47 +69,49 @@ module RBlade
|
|
63
69
|
@@handler_instances = {}
|
64
70
|
|
65
71
|
@@statement_handlers = {
|
72
|
+
"blank?" => [CompilesConditionals, :compileBlank],
|
66
73
|
"break" => [CompilesLoops, :compileBreak],
|
67
74
|
"breakif" => [CompilesLoops, :compileBreakIf],
|
68
75
|
"case" => [CompilesConditionals, :compileCase],
|
69
76
|
"checked" => [CompilesConditionals, :compileChecked],
|
70
77
|
"class" => [CompilesHtmlAttributes, :compileClass],
|
78
|
+
"defined?" => [CompilesConditionals, :compileDefined],
|
79
|
+
"delete" => [CompilesForm, :compileDelete],
|
71
80
|
"disabled" => [CompilesConditionals, :compileDisabled],
|
72
81
|
"else" => [CompilesConditionals, :compileElse],
|
73
82
|
"elsif" => [CompilesConditionals, :compileElsif],
|
74
83
|
"each" => [CompilesLoops, :compileEach],
|
75
84
|
"eachelse" => [CompilesLoops, :compileEachElse],
|
76
85
|
"empty" => [CompilesLoops, :compileEmpty],
|
86
|
+
"empty?" => [CompilesConditionals, :compileEmpty],
|
77
87
|
"end" => [CompilesStatements, :compileEnd],
|
78
|
-
"endcase" => [CompilesStatements, :compileEnd],
|
79
|
-
"endeach" => [CompilesStatements, :compileEnd],
|
80
|
-
"endeachelse" => [CompilesStatements, :compileEnd],
|
81
|
-
"endenv" => [CompilesStatements, :compileEnd],
|
82
|
-
"endfor" => [CompilesStatements, :compileEnd],
|
83
|
-
"endforelse" => [CompilesStatements, :compileEnd],
|
84
|
-
"endif" => [CompilesStatements, :compileEnd],
|
85
|
-
"endonce" => [CompilesStatements, :compileEnd],
|
86
88
|
"endprepend" => [CompilesStacks, :compileEndPrepend],
|
89
|
+
"endprependif" => [CompilesStacks, :compileEndPrependIf],
|
87
90
|
"endprependonce" => [CompilesOnce, :compileEndPrependOnce],
|
88
|
-
"endproduction" => [CompilesStatements, :compileEnd],
|
89
91
|
"endpush" => [CompilesStacks, :compileEndPush],
|
92
|
+
"endpushif" => [CompilesStacks, :compileEndPushIf],
|
90
93
|
"endpushonce" => [CompilesOnce, :compileEndPushOnce],
|
91
|
-
"endunless" => [CompilesStatements, :compileEnd],
|
92
|
-
"enduntil" => [CompilesStatements, :compileEnd],
|
93
|
-
"endwhile" => [CompilesStatements, :compileEnd],
|
94
94
|
"env" => [CompilesConditionals, :compileEnv],
|
95
95
|
"for" => [CompilesLoops, :compileFor],
|
96
96
|
"forelse" => [CompilesLoops, :compileForElse],
|
97
97
|
"if" => [CompilesConditionals, :compileIf],
|
98
|
+
"method" => [CompilesForm, :compileMethod],
|
98
99
|
"next" => [CompilesLoops, :compileNext],
|
99
100
|
"nextif" => [CompilesLoops, :compileNextIf],
|
101
|
+
"nil?" => [CompilesConditionals, :compileNil],
|
102
|
+
"old" => [CompilesForm, :compileOld],
|
100
103
|
"once" => [CompilesOnce, :compileOnce],
|
104
|
+
"patch" => [CompilesForm, :compilePatch],
|
101
105
|
"prepend" => [CompilesStacks, :compilePrepend],
|
106
|
+
"prependif" => [CompilesStacks, :compilePrependIf],
|
102
107
|
"prependonce" => [CompilesOnce, :compilePrependOnce],
|
108
|
+
"present?" => [CompilesConditionals, :compilePresent],
|
103
109
|
"production" => [CompilesConditionals, :compileProduction],
|
104
110
|
"props" => [CompilesProps, :compileProps],
|
105
111
|
"push" => [CompilesStacks, :compilePush],
|
112
|
+
"pushif" => [CompilesStacks, :compilePushIf],
|
106
113
|
"pushonce" => [CompilesOnce, :compilePushOnce],
|
114
|
+
"put" => [CompilesForm, :compilePut],
|
107
115
|
"readonly" => [CompilesConditionals, :compileReadonly],
|
108
116
|
"required" => [CompilesConditionals, :compileRequired],
|
109
117
|
"ruby" => [CompilesInlineRuby, :compile],
|
@@ -9,6 +9,46 @@ module RBlade
|
|
9
9
|
"if #{args[0]};"
|
10
10
|
end
|
11
11
|
|
12
|
+
def compileBlank args
|
13
|
+
if args&.count != 1
|
14
|
+
raise StandardError.new "Blank? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
15
|
+
end
|
16
|
+
|
17
|
+
"if (#{args[0]}).blank?;"
|
18
|
+
end
|
19
|
+
|
20
|
+
def compileDefined args
|
21
|
+
if args&.count != 1
|
22
|
+
raise StandardError.new "Defined? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
23
|
+
end
|
24
|
+
|
25
|
+
"if defined? #{args[0]};"
|
26
|
+
end
|
27
|
+
|
28
|
+
def compileEmpty args
|
29
|
+
if args&.count != 1
|
30
|
+
raise StandardError.new "Empty? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
31
|
+
end
|
32
|
+
|
33
|
+
"if (#{args[0]}).empty?;"
|
34
|
+
end
|
35
|
+
|
36
|
+
def compileNil args
|
37
|
+
if args&.count != 1
|
38
|
+
raise StandardError.new "Nil? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
39
|
+
end
|
40
|
+
|
41
|
+
"if (#{args[0]}).nil?;"
|
42
|
+
end
|
43
|
+
|
44
|
+
def compilePresent args
|
45
|
+
if args&.count != 1
|
46
|
+
raise StandardError.new "Present? statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
47
|
+
end
|
48
|
+
|
49
|
+
"if (#{args[0]}).present?;"
|
50
|
+
end
|
51
|
+
|
12
52
|
def compileElsif args
|
13
53
|
if args&.count != 1
|
14
54
|
raise StandardError.new "Elsif statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RBlade
|
2
|
+
class CompilesStatements
|
3
|
+
class CompilesForm
|
4
|
+
def compileMethod args
|
5
|
+
if args&.count != 1
|
6
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args&.count || 0}, expecting 1)"
|
7
|
+
end
|
8
|
+
method = RBlade.h(args[0].tr "\"'", "")
|
9
|
+
|
10
|
+
%[_out<<'<input type="hidden" name="_method" value="#{method}">';]
|
11
|
+
end
|
12
|
+
|
13
|
+
def compileDelete args
|
14
|
+
if !args.nil?
|
15
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
16
|
+
end
|
17
|
+
|
18
|
+
compileMethod(['DELETE'])
|
19
|
+
end
|
20
|
+
|
21
|
+
def compilePatch args
|
22
|
+
if !args.nil?
|
23
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
24
|
+
end
|
25
|
+
|
26
|
+
compileMethod(['PATCH'])
|
27
|
+
end
|
28
|
+
|
29
|
+
def compilePut args
|
30
|
+
if !args.nil?
|
31
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
32
|
+
end
|
33
|
+
|
34
|
+
compileMethod(['PUT'])
|
35
|
+
end
|
36
|
+
|
37
|
+
def compileOld args
|
38
|
+
if args.nil? || args.count > 2
|
39
|
+
raise StandardError.new "Once statement: wrong number of arguments (given #{args.count}, expecting 0)"
|
40
|
+
end
|
41
|
+
|
42
|
+
default_value = args[1] || "''"
|
43
|
+
|
44
|
+
"_out<<params.fetch(#{args[0]},#{default_value});"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -10,14 +10,23 @@ module RBlade
|
|
10
10
|
|
11
11
|
props = extractProps args[0]
|
12
12
|
props.map do |key, value|
|
13
|
+
compiled_code = ""
|
13
14
|
if value == "_required"
|
14
|
-
"if !
|
15
|
+
compiled_code << "if !attributes.has?(:'#{RBlade.escape_quotes(key)}');raise \"Props statement: #{key} is not defined\";end;"
|
16
|
+
end
|
17
|
+
if isValidVariableName key
|
18
|
+
compiled_code << "#{key}=attributes[:'#{RBlade.escape_quotes(key)}'].nil? ? #{value} : attributes[:'#{RBlade.escape_quotes(key)}'];"
|
19
|
+
compiled_code << "attributes.delete :'#{RBlade.escape_quotes(key)}';"
|
15
20
|
else
|
16
|
-
|
21
|
+
compiled_code << "attributes.default(:'#{RBlade.escape_quotes(key)}', #{value});"
|
17
22
|
end
|
23
|
+
|
24
|
+
compiled_code
|
18
25
|
end.join
|
19
26
|
end
|
20
27
|
|
28
|
+
private
|
29
|
+
|
21
30
|
def extractProps prop_string
|
22
31
|
if !prop_string.start_with?("{") || !prop_string.end_with?("}")
|
23
32
|
raise StandardError.new "Props statement: expecting hash as parameter"
|
@@ -31,9 +40,9 @@ module RBlade
|
|
31
40
|
|
32
41
|
key, value = prop.split(/^
|
33
42
|
(?:
|
34
|
-
(
|
43
|
+
'(.+)':
|
35
44
|
|
|
36
|
-
(
|
45
|
+
"(.+)":
|
37
46
|
|
|
38
47
|
([^ :]+):
|
39
48
|
|
|
@@ -56,6 +65,16 @@ module RBlade
|
|
56
65
|
|
57
66
|
props
|
58
67
|
end
|
68
|
+
|
69
|
+
RUBY_RESERVED_KEYWORDS = %w[__FILE__ __LINE__ alias and begin BEGIN break case class def defined? do else elsif end END ensure false for if in module next nil not or redo rescue retry return self super then true undef unless until when while yield].freeze
|
70
|
+
|
71
|
+
def isValidVariableName key
|
72
|
+
return false unless key.match?(/^[a-zA-Z_][a-zA-Z0-9_]*$/)
|
73
|
+
|
74
|
+
return false if RUBY_RESERVED_KEYWORDS.include? key
|
75
|
+
|
76
|
+
true
|
77
|
+
end
|
59
78
|
end
|
60
79
|
end
|
61
80
|
end
|
@@ -14,17 +14,13 @@ module RBlade
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def compilePrepend args
|
17
|
-
if args
|
18
|
-
raise StandardError.new "Prepend statement: wrong number of arguments (given #{args&.count}, expecting 1
|
17
|
+
if args&.count != 1
|
18
|
+
raise StandardError.new "Prepend statement: wrong number of arguments (given #{args&.count}, expecting 1)"
|
19
19
|
end
|
20
20
|
|
21
|
-
|
22
|
-
"RBlade::StackManager.prepend(#{args[0]}, #{args[1]});"
|
23
|
-
else
|
24
|
-
@push_counter += 1
|
21
|
+
@push_counter += 1
|
25
22
|
|
26
|
-
|
27
|
-
end
|
23
|
+
"_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
|
28
24
|
end
|
29
25
|
|
30
26
|
def compileEndPrepend args
|
@@ -37,18 +33,38 @@ module RBlade
|
|
37
33
|
"RBlade::StackManager.prepend(_p_#{@push_counter + 1}, _out);_out=_p_#{@push_counter + 1}_b;"
|
38
34
|
end
|
39
35
|
|
36
|
+
def compilePrependIf args
|
37
|
+
if args&.count != 2
|
38
|
+
raise StandardError.new "Prepend if statement: wrong number of arguments (given #{args&.count}, expecting 2)"
|
39
|
+
end
|
40
|
+
|
41
|
+
"if #{args[0]};" + compilePrepend([args[1]])
|
42
|
+
end
|
43
|
+
|
44
|
+
def compileEndPrependIf args
|
45
|
+
if !args.nil?
|
46
|
+
raise StandardError.new "End push if statement: wrong number of arguments (given #{args&.count}, expecting 0)"
|
47
|
+
end
|
48
|
+
|
49
|
+
"end;" + compileEndPush(nil)
|
50
|
+
end
|
51
|
+
|
40
52
|
def compilePush args
|
41
|
-
if args
|
42
|
-
raise StandardError.new "Push statement: wrong number of arguments (given #{args&.count}, expecting 1
|
53
|
+
if args&.count != 1
|
54
|
+
raise StandardError.new "Push statement: wrong number of arguments (given #{args&.count}, expecting 1)"
|
43
55
|
end
|
44
56
|
|
45
|
-
|
46
|
-
"RBlade::StackManager.push(#{args[0]}, #{args[1]});"
|
47
|
-
else
|
48
|
-
@push_counter += 1
|
57
|
+
@push_counter += 1
|
49
58
|
|
50
|
-
|
59
|
+
"_p_#{@push_counter}=#{args[0]};_p_#{@push_counter}_b=_out;_out='';"
|
60
|
+
end
|
61
|
+
|
62
|
+
def compilePushIf args
|
63
|
+
if args&.count != 2
|
64
|
+
raise StandardError.new "Push if statement: wrong number of arguments (given #{args&.count}, expecting 2)"
|
51
65
|
end
|
66
|
+
|
67
|
+
"if #{args[0]};" + compilePush([args[1]])
|
52
68
|
end
|
53
69
|
|
54
70
|
def compileEndPush args
|
@@ -60,6 +76,14 @@ module RBlade
|
|
60
76
|
|
61
77
|
"RBlade::StackManager.push(_p_#{@push_counter + 1}, _out);_out=_p_#{@push_counter + 1}_b;"
|
62
78
|
end
|
79
|
+
|
80
|
+
def compileEndPushIf args
|
81
|
+
if !args.nil?
|
82
|
+
raise StandardError.new "End push if statement: wrong number of arguments (given #{args&.count}, expecting 0)"
|
83
|
+
end
|
84
|
+
|
85
|
+
"end;" + compileEndPush(nil)
|
86
|
+
end
|
63
87
|
end
|
64
88
|
end
|
65
89
|
end
|
@@ -12,12 +12,12 @@ module RBlade
|
|
12
12
|
(?:
|
13
13
|
(?:
|
14
14
|
(@@)
|
15
|
-
(\w+(?!\w))
|
15
|
+
(\w+(?!\w)[!\?]?)
|
16
16
|
)
|
17
17
|
|
|
18
18
|
(?:
|
19
19
|
(@)
|
20
|
-
(\w+(?!\w))
|
20
|
+
(\w+(?!\w)[!\?]?)
|
21
21
|
(?:[ \t]*
|
22
22
|
(\(.*?\))
|
23
23
|
)?
|
@@ -45,6 +45,7 @@ module RBlade
|
|
45
45
|
i += 1
|
46
46
|
elsif segment == "@"
|
47
47
|
tokenizeStatement! segments, i
|
48
|
+
handleSpecialCases! segments, i
|
48
49
|
|
49
50
|
i += 1
|
50
51
|
elsif !segments[i].nil? && segments[i] != ""
|
@@ -74,6 +75,16 @@ module RBlade
|
|
74
75
|
segments[i] = Token.new(type: :statement, value: statement_data)
|
75
76
|
end
|
76
77
|
|
78
|
+
def handleSpecialCases!(segments, i)
|
79
|
+
case segments[i][:value][:name]
|
80
|
+
when "case"
|
81
|
+
# Remove any whitespace before a when statement
|
82
|
+
until segments[i + 1].nil? || segments[i + 1] == '@'
|
83
|
+
segments.delete_at i + 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
77
88
|
def tokenizeArguments!(segments, segment_index)
|
78
89
|
success = expandSegmentToEndParenthesis! segments, segment_index
|
79
90
|
|
data/lib/rblade/compiler.rb
CHANGED
@@ -6,6 +6,7 @@ require "rblade/compiler/compiles_verbatim"
|
|
6
6
|
require "rblade/compiler/compiles_statements"
|
7
7
|
require "rblade/compiler/tokenizes_components"
|
8
8
|
require "rblade/compiler/tokenizes_statements"
|
9
|
+
require "rblade/helpers/html_string"
|
9
10
|
|
10
11
|
Token = Struct.new(:type, :value)
|
11
12
|
|
@@ -19,6 +20,14 @@ module RBlade
|
|
19
20
|
string.gsub(/['\\\x0]/, '\\\\\0')
|
20
21
|
end
|
21
22
|
|
23
|
+
def self.e string
|
24
|
+
if string.is_a? HtmlString
|
25
|
+
string
|
26
|
+
else
|
27
|
+
h(string)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
22
31
|
class Compiler
|
23
32
|
def self.compileString(string_template)
|
24
33
|
tokens = [Token.new(:unprocessed, string_template)]
|
@@ -81,7 +81,7 @@ module RBlade
|
|
81
81
|
compiled_component = RBlade::Compiler.compileString(code)
|
82
82
|
|
83
83
|
@@component_definitions \
|
84
|
-
<< "def #{@@component_method_names[name]}(slot,attributes);_out='';" \
|
84
|
+
<< "def #{@@component_method_names[name]}(slot,attributes,params,session,flash,cookies);_out='';" \
|
85
85
|
<< "_stacks=[];" \
|
86
86
|
<< "attributes=RBlade::AttributesManager.new(attributes);" \
|
87
87
|
<< compiled_component \
|
@@ -1,5 +1,7 @@
|
|
1
|
+
require "rblade/helpers/html_string"
|
2
|
+
|
1
3
|
module RBlade
|
2
|
-
class AttributesManager
|
4
|
+
class AttributesManager < HtmlString
|
3
5
|
@attributes = {}
|
4
6
|
def initialize attributes
|
5
7
|
@attributes = attributes
|
@@ -17,12 +19,16 @@ module RBlade
|
|
17
19
|
!@attributes[key].nil?
|
18
20
|
end
|
19
21
|
|
20
|
-
def method_missing(method,
|
21
|
-
|
22
|
+
def method_missing(method, *, &block)
|
23
|
+
if [:select, :filter, :slice].include? method
|
24
|
+
AttributesManager.new @attributes.send(method, *, &block)
|
25
|
+
else
|
26
|
+
@attributes.send(method, *, &block)
|
27
|
+
end
|
22
28
|
end
|
23
29
|
|
24
30
|
def respond_to_missing?(method_name, *args)
|
25
|
-
@attributes.respond_to?(method_name)
|
31
|
+
@attributes.respond_to?(method_name)
|
26
32
|
end
|
27
33
|
|
28
34
|
def to_s attributes = nil
|
@@ -33,6 +39,10 @@ module RBlade
|
|
33
39
|
end.join " "
|
34
40
|
end
|
35
41
|
|
42
|
+
def to_str
|
43
|
+
to_s
|
44
|
+
end
|
45
|
+
|
36
46
|
def only(keys)
|
37
47
|
keys = if keys.is_a? Array
|
38
48
|
keys.map(&:to_sym)
|
@@ -40,7 +50,7 @@ module RBlade
|
|
40
50
|
[keys.to_sym]
|
41
51
|
end
|
42
52
|
|
43
|
-
|
53
|
+
AttributesManager.new @attributes.slice(*keys)
|
44
54
|
end
|
45
55
|
|
46
56
|
def except(keys)
|
@@ -50,7 +60,15 @@ module RBlade
|
|
50
60
|
[keys.to_sym]
|
51
61
|
end
|
52
62
|
|
53
|
-
|
63
|
+
AttributesManager.new @attributes.except(*keys)
|
64
|
+
end
|
65
|
+
|
66
|
+
def class(new_classes)
|
67
|
+
new_classes = ClassManager.new(new_classes).to_s
|
68
|
+
attributes = @attributes.dup
|
69
|
+
attributes[:class] = mergeClasses attributes[:class], new_classes
|
70
|
+
|
71
|
+
AttributesManager.new attributes
|
54
72
|
end
|
55
73
|
|
56
74
|
def merge(default_attributes)
|
@@ -70,7 +88,19 @@ module RBlade
|
|
70
88
|
new_attributes[key] = value
|
71
89
|
end
|
72
90
|
|
73
|
-
|
91
|
+
AttributesManager.new new_attributes
|
92
|
+
end
|
93
|
+
|
94
|
+
def has?(*keys)
|
95
|
+
keys.map!(&:to_sym)
|
96
|
+
|
97
|
+
keys.all? { |key| @attributes.has_key? key }
|
98
|
+
end
|
99
|
+
|
100
|
+
def has_any?(*keys)
|
101
|
+
keys.map!(&:to_sym)
|
102
|
+
|
103
|
+
keys.any? { |key| @attributes.has_key? key }
|
74
104
|
end
|
75
105
|
|
76
106
|
private
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "rblade/helpers/attributes_manager"
|
2
|
+
require "rblade/helpers/html_string"
|
3
|
+
|
4
|
+
module RBlade
|
5
|
+
class SlotManager < HtmlString
|
6
|
+
def initialize content, attributes = nil
|
7
|
+
@content = content
|
8
|
+
@attributes = attributes && AttributesManager.new(attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
@content
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_str
|
16
|
+
to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(method, *)
|
20
|
+
@content.send(method, *)
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(method_name, *args)
|
24
|
+
@content.respond_to?(method_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def attributes
|
28
|
+
@attributes
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -3,6 +3,7 @@ require "rblade/compiler"
|
|
3
3
|
require "rblade/component_store"
|
4
4
|
require "rblade/helpers/attributes_manager"
|
5
5
|
require "rblade/helpers/class_manager"
|
6
|
+
require "rblade/helpers/slot_manager"
|
6
7
|
require "rblade/helpers/stack_manager"
|
7
8
|
require "rblade/helpers/style_manager"
|
8
9
|
|
data/rblade.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rblade"
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.6.1"
|
4
4
|
s.summary = "A component-first templating engine for Rails"
|
5
5
|
s.description = "RBlade is a simple, yet powerful templating engine for Ruby on Rails, inspired by Laravel Blade."
|
6
6
|
s.authors = ["Simon J"]
|