jasonette-rails 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/Rakefile +0 -1
  4. data/lib/jasonette-rails.rb +1 -0
  5. data/lib/jasonette.rb +26 -11
  6. data/lib/jasonette/action_view_extensions.rb +15 -0
  7. data/lib/jasonette/core/action.rb +34 -0
  8. data/lib/jasonette/core/base.rb +177 -60
  9. data/lib/jasonette/core/body.rb +14 -0
  10. data/lib/jasonette/core/body/footer.rb +7 -0
  11. data/lib/jasonette/core/body/footer/input.rb +24 -0
  12. data/lib/jasonette/core/body/footer/tabs.rb +11 -0
  13. data/lib/jasonette/core/body/header.rb +21 -0
  14. data/lib/jasonette/core/body/header/search.rb +6 -0
  15. data/lib/jasonette/core/body/layers.rb +4 -0
  16. data/lib/jasonette/core/body/sections.rb +5 -0
  17. data/lib/jasonette/core/components.rb +0 -9
  18. data/lib/jasonette/core/data.rb +4 -0
  19. data/lib/jasonette/core/item.rb +21 -0
  20. data/lib/jasonette/core/items.rb +99 -14
  21. data/lib/jasonette/core/layout.rb +2 -5
  22. data/lib/jasonette/core/map.rb +6 -0
  23. data/lib/jasonette/core/options.rb +9 -0
  24. data/lib/jasonette/{jason/body/header.rb → core/pins.rb} +1 -1
  25. data/lib/jasonette/core/properties.rb +151 -22
  26. data/lib/jasonette/engine.rb +10 -0
  27. data/lib/jasonette/handler.rb +14 -0
  28. data/lib/jasonette/helpers.rb +38 -0
  29. data/lib/jasonette/jason/body.rb +2 -9
  30. data/lib/jasonette/jason/head.rb +22 -2
  31. data/lib/jasonette/jason/head/actions.rb +5 -0
  32. data/lib/jasonette/jason/head/templates.rb +5 -0
  33. data/lib/jasonette/railtie.rb +30 -0
  34. data/lib/jasonette/template.rb +201 -0
  35. data/lib/jasonette/version.rb +1 -1
  36. metadata +55 -23
  37. data/lib/jasonette/core/sections.rb +0 -9
  38. data/lib/jasonette/jason/body/header/search.rb +0 -5
  39. data/lib/jasonette/jbuilder_extensions.rb +0 -19
@@ -0,0 +1,7 @@
1
+ module Jasonette
2
+ class Body::Footer < Jasonette::Base
3
+ property :style
4
+ property :tabs
5
+ property :input
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ module Jasonette
2
+ class Body::Footer::Input < Jasonette::Base
3
+ property :style
4
+
5
+ def left uri=nil, &block
6
+ append Jasonette::Items.new(context).image(uri, true, "image", &block), "left"
7
+ end
8
+
9
+ def right caption=nil, &block
10
+ append Jasonette::Items.new(context).label(caption, true, &block), "right"
11
+ end
12
+
13
+ def textfield name=nil, value=nil, &block
14
+ append Jasonette::Items.new(context).textfield(name, value, true, &block), "textfield"
15
+ end
16
+
17
+ private
18
+ def append builder, msg
19
+ @attributes[msg] ||= {}
20
+ @attributes[msg].merge! builder.attributes!
21
+ builder
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module Jasonette
2
+ class Body::Footer::Tabs < Jasonette::Base
3
+ property :style
4
+ property :items
5
+
6
+ def attributes!
7
+ super
8
+ @attributes.merge! items.attributes!
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ module Jasonette
2
+ class Body::Header < Jasonette::Base
3
+ property :style
4
+
5
+ def menu caption=nil, image_uri=nil
6
+ item = Jasonette::Item.new(context) do
7
+ text caption unless caption.nil?
8
+ image image_uri unless image_uri.nil?
9
+ encode(&::Proc.new) if block_given?
10
+ end
11
+ append item, "menu"
12
+ end
13
+
14
+ private
15
+ def append builder, msg
16
+ @attributes[msg] ||= {}
17
+ @attributes[msg].merge! builder.attributes!
18
+ builder
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ module Jasonette
2
+ class Body::Header::Search < Jasonette::Base
3
+ property :style
4
+ property :action
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module Jasonette
2
+ class Body::Layers < Jasonette::Items
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Jasonette
2
+ class Body::Sections < Jasonette::Base
3
+ property :items
4
+ end
5
+ end
@@ -1,13 +1,4 @@
1
1
  module Jasonette
2
2
  class Components < Jasonette::Items
3
-
4
- private
5
-
6
- def append builder
7
- @attributes["components"] ||= []
8
- @attributes["components"] << builder.attributes!
9
- self
10
- end
11
-
12
3
  end
13
4
  end
@@ -0,0 +1,4 @@
1
+ module Jasonette
2
+ class Data < Jasonette::Base
3
+ end
4
+ end
@@ -0,0 +1,21 @@
1
+ module Jasonette
2
+ class Item < Jasonette::Base
3
+ property :action
4
+ property :style
5
+
6
+ def badge caption=nil
7
+ item = self.class.new(context) do
8
+ text caption unless caption.nil?
9
+ encode(&::Proc.new) if block_given?
10
+ end
11
+ append item, "badge"
12
+ end
13
+
14
+ private
15
+ def append builder, msg
16
+ @attributes[msg] ||= {}
17
+ @attributes[msg].merge! builder.attributes!
18
+ builder
19
+ end
20
+ end
21
+ end
@@ -1,28 +1,112 @@
1
1
  module Jasonette
2
2
  class Items < Jasonette::Base
3
3
 
4
- def label caption=nil
5
- item = Jasonette::Base.new(@context) do
4
+ def label caption=nil, skip_type=false
5
+ item = Jasonette::Item.new(context) do
6
6
  text caption unless caption.nil?
7
- type "label"
8
- with_attributes { instance_eval(&::Proc.new) } if block_given?
7
+ type "label" unless skip_type
8
+ encode(&::Proc.new) if block_given?
9
9
  end
10
10
  append item
11
11
  end
12
12
 
13
- def image uri=nil
14
- item = Jasonette::Base.new(@context) do
15
- type "image"
16
- url uri unless uri.nil?
17
- with_attributes { instance_eval(&::Proc.new) } if block_given?
13
+ def text caption=nil, skip_type=false
14
+ item = Jasonette::Item.new(context) do
15
+ text caption unless caption.nil?
16
+ type "text" unless skip_type
17
+ encode(&::Proc.new) if block_given?
18
+ end
19
+ append item
20
+ end
21
+
22
+ def video uri=nil, skip_type=false
23
+ item = Jasonette::Item.new(context) do
24
+ type "video" unless skip_type
25
+ file_url uri unless uri.nil?
26
+ encode(&::Proc.new) if block_given?
27
+ end
28
+ append item
29
+ end
30
+
31
+ def image uri=nil, skip_type=false, url_key="url"
32
+ item = Jasonette::Item.new(context) do
33
+ type "image" unless skip_type
34
+ set! url_key, uri unless uri.nil?
35
+ encode(&::Proc.new) if block_given?
36
+ end
37
+ append item
38
+ end
39
+
40
+ def button caption=nil, is_url=false, skip_type=false
41
+ item = Jasonette::Item.new(context) do
42
+ type "button" unless skip_type
43
+ unless caption.nil?
44
+ is_url ? (url caption) : (text caption)
45
+ end
46
+ encode(&::Proc.new) if block_given?
47
+ end
48
+ append item
49
+ end
50
+
51
+ def slider name, value=nil, skip_type=false
52
+ item = Jasonette::Item.new(context) do
53
+ type "slider" unless skip_type
54
+ name name
55
+ value value unless value.nil?
56
+ encode(&::Proc.new) if block_given?
18
57
  end
19
58
  append item
20
59
  end
21
60
 
22
61
  def layout orientation="vertical"
23
- item = Jasonette::Layout.new(@context) do
62
+ item = Jasonette::Layout.new(context) do
24
63
  type orientation
25
- with_attributes { instance_eval(&::Proc.new) } if block_given?
64
+ encode(&::Proc.new) if block_given?
65
+ end
66
+ append item
67
+ end
68
+
69
+ def textfield name=nil, value=nil, skip_type=false
70
+ item = Jasonette::Item.new(context) do
71
+ type "textfield" unless skip_type
72
+ name name unless name.nil?
73
+ value value unless value.nil?
74
+ encode(&::Proc.new) if block_given?
75
+ end
76
+ append item
77
+ end
78
+
79
+ def textarea name=nil, value=nil, skip_type=false
80
+ item = Jasonette::Item.new(context) do
81
+ type "textarea" unless skip_type
82
+ name name unless name.nil?
83
+ value value unless value.nil?
84
+ encode(&::Proc.new) if block_given?
85
+ end
86
+ append item
87
+ end
88
+
89
+ def space height=nil, skip_type=false
90
+ item = Jasonette::Item.new(context) do
91
+ type "space" unless skip_type
92
+ height height unless height.nil?
93
+ encode(&::Proc.new) if block_given?
94
+ end
95
+ append item
96
+ end
97
+
98
+ def map skip_type=false
99
+ item = Jasonette::Map.new(context) do
100
+ type "map" unless skip_type
101
+ encode(&::Proc.new) if block_given?
102
+ end
103
+ append item
104
+ end
105
+
106
+ def merge! items
107
+ item = Jasonette::Item.new(context) do
108
+ merge! items
109
+ encode(&::Proc.new) if block_given?
26
110
  end
27
111
  append item
28
112
  end
@@ -30,9 +114,10 @@ module Jasonette
30
114
  private
31
115
 
32
116
  def append builder
33
- @attributes["items"] ||= []
34
- @attributes["items"] << builder.attributes!
35
- self
117
+ @attributes = [] if @attributes.empty?
118
+ raise "HashError : You may have used `set!` before" if ::Hash === @attributes
119
+ @attributes << builder.attributes!
120
+ builder
36
121
  end
37
122
 
38
123
  end
@@ -1,9 +1,6 @@
1
1
  module Jasonette
2
- class Layout < Jasonette::Base
2
+ class Layout < Jasonette::Item
3
+ super_property
3
4
  property :components
4
-
5
- def attributes!
6
- @attributes.merge components.attributes!
7
- end
8
5
  end
9
6
  end
@@ -0,0 +1,6 @@
1
+ module Jasonette
2
+ class Map < Jasonette::Item
3
+ super_property
4
+ property :pins, :is_many
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module Jasonette
2
+ class Options < Jasonette::Base
3
+ property :data, :is_many, :is_single
4
+ property :action
5
+ property :form, :is_many
6
+ property :items
7
+ property :options
8
+ end
9
+ end
@@ -1,5 +1,5 @@
1
1
  module Jasonette
2
- class Jason::Body::Header < Jasonette::Base
2
+ class Pins < Jasonette::Base
3
3
  property :style
4
4
  end
5
5
  end
@@ -1,11 +1,41 @@
1
1
  module Jasonette::Properties
2
+ TYPES = [:is_many, :is_single]
3
+ DEFAULT_IS_ARRAY = [:items, :components, :layers]
4
+
5
+ class PropertyEnum
6
+ include Enumerable
7
+ attr_accessor :properties
8
+
9
+ def initialize properties = {}
10
+ @properties = properties
11
+ end
12
+
13
+ def merge! value
14
+ properties.merge! value if value.is_a? Hash
15
+ properties.merge! value.properties if value.is_a? self.class
16
+ end
17
+
18
+ def names; properties.keys end
19
+ def value; properties end
20
+
21
+ def has_type?(name, ptype)
22
+ value[name.to_sym][ptype.to_sym] rescue false
23
+ end
24
+ end
25
+
2
26
  module ClassMethods
3
- def property name
4
- properties << name
27
+
28
+ def super_property
29
+ properties.merge!(superclass.properties)
30
+ end
31
+
32
+ def property name, *types
33
+ types << :is_many if DEFAULT_IS_ARRAY.include?(name)
34
+ properties.merge! "#{name}".to_sym => TYPES.map { |type| { type => types.include?(type) } }.reduce({}, :merge)
5
35
  end
6
36
 
7
37
  def properties
8
- @properties ||= []
38
+ PropertyEnum.new @properties ||= {}
9
39
  end
10
40
  end
11
41
 
@@ -13,8 +43,44 @@ module Jasonette::Properties
13
43
  base.send :extend, ClassMethods
14
44
  end
15
45
 
16
- def properties
17
- self.class.properties
46
+ def property_names
47
+ self.class.properties.names
48
+ end
49
+
50
+ def property_variables
51
+ property_names.map { |i| "@#{i}".to_sym }
52
+ end
53
+
54
+ TYPES.each do |type|
55
+ define_method("#{type}?") { |name| self.class.properties.has_type?(name, type) }
56
+ define_method("ivar_#{type}_for_property") { |name| "@#{type}_#{name}" }
57
+ define_method("get_#{type}_ivar") do |name|
58
+ instance_variable_get(send("ivar_#{type}_for_property", name)) || (is_many?(name) ? [] : nil)
59
+ end
60
+ define_method("set_#{type}_ivar") do |name, value|
61
+ instance_variable_set(send("ivar_#{type}_for_property", name), value)
62
+ end
63
+ end
64
+ define_method("property_type_methods") { TYPES.map { |type| "#{type}?" } }
65
+
66
+ def has_any_property_type? name
67
+ property_type_methods.map { |m| send(m, name) }.any?
68
+ end
69
+
70
+ def has_property? name
71
+ property_names.include?(name.to_sym)
72
+ end
73
+
74
+ def ivar_for_property name
75
+ "@#{name}"
76
+ end
77
+
78
+ def set_ivar name, value
79
+ instance_variable_set(ivar_for_property(name), value)
80
+ end
81
+
82
+ def get_ivar name
83
+ instance_variable_get(ivar_for_property(name))
18
84
  end
19
85
 
20
86
  def prop name
@@ -22,8 +88,8 @@ module Jasonette::Properties
22
88
  end
23
89
 
24
90
  def properties_empty?
25
- properties.all? do |ivar_name|
26
- ivar = instance_variable_get(:"@#{ivar_name}")
91
+ property_names.all? do |ivar_name|
92
+ ivar = get_ivar(ivar_name)
27
93
  ivar.nil? || ivar.empty?
28
94
  end
29
95
  end
@@ -35,37 +101,100 @@ module Jasonette::Properties
35
101
  klass
36
102
  end
37
103
 
38
- def property_get! name
39
- ivar_name = "@#{name}"
40
- if instance_variable_get(ivar_name).nil?
41
- klass = klass_for_property name
42
- instance_variable_set(ivar_name, klass.new(@context))
104
+ def parent_jasonette_set klass
105
+ instance_variable_set("@_parent_jasonette", klass)
106
+
107
+ (klass.instance_variables - klass.property_variables).each do |var|
108
+ instance_variable_set(var, klass.instance_variable_get(var)) unless instance_variable_get(var)
109
+ end
110
+ klass
111
+ end
112
+
113
+ def parent_jasonette
114
+ instance_variable_get("@_parent_jasonette")
115
+ end
116
+
117
+ def create_new_klass name
118
+ klass = klass_for_property name
119
+ new_klass = klass.new(@context)
120
+ new_klass.parent_jasonette_set self
121
+ new_klass
122
+ end
123
+
124
+ def all_instance_variable_set name, *args
125
+ new_klass = create_new_klass name
126
+
127
+ set_ivar(name, new_klass) if (get_ivar(name).nil? || is_many?(name))
128
+ ivar = get_ivar(name)
129
+
130
+ if is_single?(name)
131
+ new_klass.set_is_single_ivar(name, args.first)
132
+ end
133
+
134
+ if is_many?(name)
135
+ ivar_all = get_is_many_ivar(name)
136
+ set_is_many_ivar(name, ivar_all << ivar)
43
137
  end
44
- instance_variable_get(ivar_name)
138
+ end
139
+
140
+ def property_get! name, *args
141
+ all_instance_variable_set(name, *args)
142
+ get_ivar(name)
45
143
  end
46
144
 
47
145
  def property_set! name, *args, &block
48
- ivar = property_get! name
146
+ ivar = property_get! name, *args
49
147
  return ivar unless block_given?
50
148
  ivar.tap { |v| v.encode(&block) }
51
149
  end
52
150
 
151
+ def get_default_for_property name
152
+ is_many_ivars = get_is_many_ivar(name)
153
+
154
+ single_default = is_single?(name) && is_many_ivars.to_a.length <= 1 ? {} : nil
155
+ many_default = is_many?(name) ? [] : nil
156
+ single_default || many_default || {}
157
+ end
158
+
53
159
  def merge_properties
54
- properties.each do |property_name|
55
- ivar = instance_variable_get(:"@#{property_name}")
160
+ property_names.each do |property_name|
161
+ property_name = property_name.to_s
162
+ ivar = get_ivar(property_name)
56
163
  next if ivar.nil? || ivar.empty?
57
- @attributes[property_name.to_s] ||= {}
58
- @attributes[property_name.to_s].merge! ivar.attributes!
164
+ @attributes[property_name] = get_default_for_property(property_name)
165
+
166
+ if !has_any_property_type?(property_name)
167
+ @attributes[property_name].merge! ivar.attributes!
168
+ next
169
+ end
170
+
171
+ if is_many?(property_name)
172
+ get_is_many_ivar(property_name).each do |iv|
173
+ ivar_attributes = iv.attributes!
174
+ if is_single?(property_name) && (single_ivar = iv.get_is_single_ivar(property_name))
175
+ @attributes[property_name] = @attributes[property_name].reduce({}, :merge) if ::Array === @attributes[property_name]
176
+ @attributes[property_name][single_ivar] ||= {}
177
+ @attributes[property_name][single_ivar].merge! ivar_attributes
178
+ else
179
+ if ::Hash === @attributes[property_name]
180
+ @attributes[property_name].merge! ivar_attributes
181
+ elsif DEFAULT_IS_ARRAY.map(&:to_s).include?(property_name) && ::Array === ivar_attributes
182
+ @attributes[property_name] += ivar_attributes
183
+ else
184
+ @attributes[property_name] << ivar_attributes
185
+ end
186
+ end
187
+ end
188
+ end
59
189
  end
60
190
  end
61
191
 
62
192
  def property_sender target, name, *args, &block
193
+ raise "unhandled definition! : use different property name then `#{name}`" if Object.new.methods.include?(name.to_sym)
63
194
  if block_given?
64
- target.send name, *args, &block
195
+ target.set! name, _scope { block.call }
65
196
  elsif args.one? && args.first.is_a?(Hash)
66
- target.send name do
67
- args.first.each{ |key, value| json.set! key, value.to_s }
68
- end
197
+ target.set! name, args.first
69
198
  else
70
199
  raise "unhandled definition!"
71
200
  end