jasonette-rails 0.1.2 → 0.2.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.
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