Neurogami-jimpanzee 1.0.2.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.
- data/History.txt +3 -0
- data/Jimpanzee.gemspec +0 -0
- data/Manifest.txt +62 -0
- data/README.md +23 -0
- data/Rakefile +98 -0
- data/bin/jimpanzee +41 -0
- data/lib/monkeybars.rb +7 -0
- data/lib/monkeybars/controller.rb +608 -0
- data/lib/monkeybars/debug.rb +69 -0
- data/lib/monkeybars/event_handler.rb +89 -0
- data/lib/monkeybars/event_handler_registration_and_dispatch_mixin.rb +251 -0
- data/lib/monkeybars/exceptions.rb +10 -0
- data/lib/monkeybars/global_error_handler.rb +34 -0
- data/lib/monkeybars/inflector.rb +68 -0
- data/lib/monkeybars/key.rb +206 -0
- data/lib/monkeybars/task_processor.rb +47 -0
- data/lib/monkeybars/validated_hash.rb +22 -0
- data/lib/monkeybars/view.rb +609 -0
- data/lib/monkeybars/view_mapping.rb +379 -0
- data/lib/monkeybars/view_nesting.rb +114 -0
- data/lib/monkeybars/view_positioning.rb +66 -0
- data/skeleton/Rakefile +5 -0
- data/skeleton/lib/java/README.txt +1 -0
- data/skeleton/lib/java/monkeybars-1.0.2.1.jar +0 -0
- data/skeleton/lib/ruby/README.md +1 -0
- data/skeleton/lib/ruby/README.txt +1 -0
- data/skeleton/src/application_controller.rb +4 -0
- data/skeleton/src/application_view.rb +3 -0
- data/skeleton/src/main.rb +52 -0
- data/skeleton/src/manifest.rb +58 -0
- data/skeleton/src/resolver.rb +33 -0
- data/skeleton/tasks/monkeybars.rake +89 -0
- metadata +99 -0
@@ -0,0 +1,379 @@
|
|
1
|
+
require 'monkeybars/validated_hash'
|
2
|
+
|
3
|
+
module Monkeybars
|
4
|
+
# This is an internal class used only by Monkeybars::View
|
5
|
+
#
|
6
|
+
# A Mapping records the relationship between the fields of a model or
|
7
|
+
# transfer hash and the fields of a view. Mappings are created for each call
|
8
|
+
# to View.map. During first usage, the mappings are inspected for validity
|
9
|
+
# and are assigned a type (one of the constants defined in Mapping) to speed
|
10
|
+
# up processing. Invalid mappings raise an exception.
|
11
|
+
class Mapping #:nodoc:
|
12
|
+
DIRECTION_TO_VIEW = :to_view
|
13
|
+
DIRECTION_FROM_VIEW = :from_view
|
14
|
+
DIRECTION_BOTH = :both
|
15
|
+
MODEL = :model
|
16
|
+
TRANSFER = :transfer
|
17
|
+
|
18
|
+
class << self
|
19
|
+
alias_method :__new__, :new
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.new(mapping_options = {})
|
23
|
+
mapping_options.validate_only(:view, :model, :transfer, :using, :ignoring, :translate_using)
|
24
|
+
mapping_options.extend HashMappingValidation
|
25
|
+
|
26
|
+
if mapping_options.properties_only?
|
27
|
+
PropertyMapping.__new__(mapping_options)
|
28
|
+
elsif mapping_options.methods_only?
|
29
|
+
RawMapping.__new__(mapping_options)
|
30
|
+
elsif mapping_options.both_properties_and_methods?
|
31
|
+
MethodMapping.__new__(mapping_options)
|
32
|
+
else
|
33
|
+
raise InvalidMappingError, "Cannot determine mapping type with parameters #{mapping_options.inspect}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(mapping_options = {})
|
38
|
+
@view_property = mapping_options[:view] || nil
|
39
|
+
@model_property = mapping_options[:model] || nil
|
40
|
+
@transfer_property = mapping_options[:transfer] || nil
|
41
|
+
@data_translation_hash = mapping_options[:translate_using]
|
42
|
+
|
43
|
+
@to_view_method, @from_view_method = if mapping_options[:using]
|
44
|
+
if mapping_options[:using].kind_of? Array
|
45
|
+
[mapping_options[:using][0], mapping_options[:using][1]]
|
46
|
+
else
|
47
|
+
[mapping_options[:using], nil]
|
48
|
+
end
|
49
|
+
else
|
50
|
+
[nil, nil]
|
51
|
+
end
|
52
|
+
|
53
|
+
@event_types_to_ignore = if mapping_options[:ignoring]
|
54
|
+
if mapping_options[:ignoring].kind_of? Array
|
55
|
+
mapping_options[:ignoring]
|
56
|
+
else
|
57
|
+
[mapping_options[:ignoring]]
|
58
|
+
end
|
59
|
+
else
|
60
|
+
[]
|
61
|
+
end
|
62
|
+
|
63
|
+
if mapping_options.both_model_and_transfer_present?
|
64
|
+
raise InvalidMappingError, "Both model and transfer parameters were given"
|
65
|
+
elsif mapping_options.at_least_one_property_present? and !mapping_options.both_properties_present?
|
66
|
+
raise InvalidMappingError, "Both a view and a model/transfer property must be provided"
|
67
|
+
end
|
68
|
+
set_direction(mapping_options)
|
69
|
+
end
|
70
|
+
|
71
|
+
def maps_to_view?
|
72
|
+
(DIRECTION_BOTH == @direction) or (DIRECTION_TO_VIEW == @direction)
|
73
|
+
end
|
74
|
+
|
75
|
+
def maps_from_view?
|
76
|
+
(DIRECTION_BOTH == @direction) or (DIRECTION_FROM_VIEW == @direction)
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_view(view, model, transfer)
|
80
|
+
disable_declared_handlers(view) do
|
81
|
+
if model_mapping?
|
82
|
+
model_to_view(view, model)
|
83
|
+
else
|
84
|
+
transfer_to_view(view, transfer) if mapped_transfer_key_present?(transfer)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def from_view(view, model, transfer)
|
90
|
+
disable_declared_handlers(view) do
|
91
|
+
if model_mapping?
|
92
|
+
model_from_view(view, model)
|
93
|
+
elsif transfer_mapping?
|
94
|
+
transfer_from_view(view, transfer)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def model_mapping?
|
100
|
+
!@model_property.nil?
|
101
|
+
end
|
102
|
+
|
103
|
+
def transfer_mapping?
|
104
|
+
!@transfer_property.nil?
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def mapped_transfer_key_present?(transfer)
|
110
|
+
transfer.has_key? @transfer_property
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_direction(mapping_options)
|
114
|
+
@direction = if mapping_options.both_methods_present?
|
115
|
+
DIRECTION_BOTH
|
116
|
+
elsif mapping_options.to_view_method_present?
|
117
|
+
DIRECTION_TO_VIEW
|
118
|
+
else
|
119
|
+
DIRECTION_FROM_VIEW
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def disable_declared_handlers(view, &block)
|
124
|
+
if @event_types_to_ignore.empty?
|
125
|
+
yield
|
126
|
+
else
|
127
|
+
field = view.get_field_value(/^(\w+)\.?/.match(@view_property)[1])
|
128
|
+
@event_types_to_ignore.each do |event_type|
|
129
|
+
unless event_type.to_s == "document"
|
130
|
+
field.disable_handlers(event_type, &block)
|
131
|
+
else
|
132
|
+
field.document.disable_handlers(event_type, &block)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class BasicPropertyMapping < Mapping
|
140
|
+
def to_s
|
141
|
+
model_or_transfer_key = model_mapping? ? ':model' : ':transfer'
|
142
|
+
model_or_transfer_property = model_mapping? ? @model_property : @transfer_property
|
143
|
+
":view => #{@view_property.inspect}, #{model_or_transfer_key} => #{model_or_transfer_property.inspect}"
|
144
|
+
end
|
145
|
+
|
146
|
+
def model_to_view(view, model)
|
147
|
+
begin
|
148
|
+
instance_eval("view.#{@view_property} = model.#{@model_property}", __FILE__, __LINE__)
|
149
|
+
rescue NoMethodError
|
150
|
+
raise InvalidMappingError, "Either model.#{@model_property} or self.#{@view_property} in #{view.class} is not valid."
|
151
|
+
rescue TypeError => e
|
152
|
+
raise InvalidMappingError, "Invalid types when assigning from model.#{@model_property} to self.#{@view_property}, #{e.message} in #{view.class}"
|
153
|
+
rescue Monkeybars::UndefinedComponentError
|
154
|
+
raise InvalidMappingError, "The view property #{@view_property} was not found on view #{view.class}"
|
155
|
+
rescue SyntaxError, Exception => e
|
156
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def transfer_to_view(view, transfer)
|
161
|
+
begin
|
162
|
+
instance_eval("view.#{@view_property} = transfer[#{@transfer_property.inspect}]", __FILE__, __LINE__)
|
163
|
+
rescue NoMethodError
|
164
|
+
raise InvalidMappingError, "Either transfer[#{@transfer_property.inspect}] or self.#{@view_property} in #{view.class} is not valid."
|
165
|
+
rescue TypeError => e
|
166
|
+
raise InvalidMappingError, "Invalid types when assigning from transfer[#{@transfer_property.inspect}] to self.#{@view_property}, #{e.class}: #{e.message} in #{view.class}"
|
167
|
+
rescue SyntaxError, Exception => e
|
168
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def model_from_view(view, model)
|
173
|
+
begin
|
174
|
+
instance_eval("model.#{@model_property} = view.#{@view_property}", __FILE__, __LINE__)
|
175
|
+
rescue NoMethodError
|
176
|
+
raise InvalidMappingError, "Either model.#{@model_property} or self.#{@view_property} in #{view.class} is not valid."
|
177
|
+
rescue TypeError => e
|
178
|
+
raise InvalidMappingError, "Invalid types when assigning from model.#{@model_property} to self.#{@view_property}, #{e.message} in #{view.class}"
|
179
|
+
rescue SyntaxError, Exception => e
|
180
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def transfer_from_view(view, transfer)
|
185
|
+
begin
|
186
|
+
instance_eval("transfer[#{@transfer_property.inspect}] = view.#{@view_property}", __FILE__, __LINE__)
|
187
|
+
rescue NoMethodError
|
188
|
+
raise InvalidMappingError, "Either transfer[#{@transfer_property.inspect}] or self.#{@view_property} in #{view.class} is not valid."
|
189
|
+
rescue TypeError => e
|
190
|
+
raise InvalidMappingError, "Invalid types when assigning from transfer[#{@transfer_property.inspect}] to self.#{@view_property}, #{e.message} in #{view.class}"
|
191
|
+
rescue SyntaxError, Exception => e
|
192
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
def self.new(*args)
|
198
|
+
raise "#{self} is not a concrete class"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class RawMapping < Mapping
|
203
|
+
def to_view(view, model, transfer)
|
204
|
+
disable_declared_handlers(view) do
|
205
|
+
view.method(@to_view_method).call(model, transfer)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def from_view(view, model, transfer)
|
210
|
+
view.method(@from_view_method).call(model, transfer) unless @from_view_method.nil?
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
class PropertyMapping < BasicPropertyMapping
|
215
|
+
def set_direction(mapping_options)
|
216
|
+
@direction = DIRECTION_BOTH
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
class MethodMapping < BasicPropertyMapping
|
221
|
+
|
222
|
+
def initialize(mapping_properties)
|
223
|
+
super
|
224
|
+
if using_translation?
|
225
|
+
@to_view_translation = @data_translation_hash
|
226
|
+
@from_view_translation = @data_translation_hash.invert
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def to_s
|
231
|
+
using_key = using_translation? ? ':using_translation' : ':using'
|
232
|
+
using_value = using_translation? ? @data_translation_hash.inspect : "[#{@to_view_method.inspect}, #{@from_view_method.inspect}]"
|
233
|
+
super << " #{using_key} => #{using_value}"
|
234
|
+
end
|
235
|
+
|
236
|
+
def using_translation?
|
237
|
+
!@data_translation_hash.nil?
|
238
|
+
end
|
239
|
+
|
240
|
+
def model_to_view(view, model)
|
241
|
+
if using_translation?
|
242
|
+
model_data = instance_eval("model.#{@model_property}", __FILE__, __LINE__)
|
243
|
+
unless @to_view_translation.has_key? model_data
|
244
|
+
raise TranslationError, "The key #{model_data.inspect} for model #{model.class} does not exist #{@to_view_translation.inspect}"
|
245
|
+
end
|
246
|
+
|
247
|
+
instance_eval("view.#{@view_property} = @to_view_translation[model_data]", __FILE__, __LINE__)
|
248
|
+
elsif :default == @to_view_method
|
249
|
+
super
|
250
|
+
else
|
251
|
+
instance_eval("view.#{@view_property} = view.method(@to_view_method).call(model.#{@model_property})", __FILE__, __LINE__)
|
252
|
+
end
|
253
|
+
rescue NameError => e
|
254
|
+
raise InvalidMappingError, "Either view.#{@view_property} or view.#{@to_view_method}(#{@model_property}) is not valid.\nOriginal error: #{e}\n#{e.message}"
|
255
|
+
rescue SyntaxError, Exception => e
|
256
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}"
|
257
|
+
end
|
258
|
+
|
259
|
+
def transfer_to_view(view, transfer)
|
260
|
+
if using_translation?
|
261
|
+
transfer_data = instance_eval("transfer[#{@transfer_property.inspect}]", __FILE__, __LINE__)
|
262
|
+
unless @to_view_translation.has_key? transfer_data
|
263
|
+
raise TranslationError, "The key #{transfer_data.inspect} for transfer does not exist #{@to_view_translation.inspect}"
|
264
|
+
end
|
265
|
+
instance_eval("view.#{@view_property} = @to_view_translation[transfer_data]", __FILE__, __LINE__)
|
266
|
+
elsif :default == @to_view_method
|
267
|
+
super
|
268
|
+
else
|
269
|
+
instance_eval("view.#{@view_property} = view.method(@to_view_method).call(transfer[#{@transfer_property.inspect}])", __FILE__, __LINE__)
|
270
|
+
end
|
271
|
+
rescue NameError => e
|
272
|
+
raise InvalidMappingError, "Either view.#{@view_property} or view.#{@to_view_method}(#{@transfer_property}) is not valid.\nOriginal error: #{e}\n#{e.message}"
|
273
|
+
rescue SyntaxError, Exception => e
|
274
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}"
|
275
|
+
end
|
276
|
+
|
277
|
+
def model_from_view(view, model)
|
278
|
+
if using_translation?
|
279
|
+
view_data = instance_eval("view.#{@view_property}", __FILE__, __LINE__)
|
280
|
+
unless @from_view_translation.has_key? view_data
|
281
|
+
raise TranslationError, "The key #{view_data.inspect} for view #{view.class} does not exist #{@from_view_translation.inspect}"
|
282
|
+
end
|
283
|
+
instance_eval("model.#{@model_property} = @from_view_translation[view_data]", __FILE__, __LINE__)
|
284
|
+
elsif :default == @from_view_method
|
285
|
+
super
|
286
|
+
else
|
287
|
+
instance_eval("model.#{@model_property} = view.method(@from_view_method).call(view.#{@view_property})", __FILE__, __LINE__)
|
288
|
+
end
|
289
|
+
rescue NameError => e
|
290
|
+
raise InvalidMappingError, "Either model.#{@model_property} or view.#{@from_view_method}(#{@view_property}) is not valid.\nOriginal error: #{e}\n#{e.message}"
|
291
|
+
rescue SyntaxError, Exception => e
|
292
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}", e.backtrace
|
293
|
+
end
|
294
|
+
|
295
|
+
def transfer_from_view(view, transfer)
|
296
|
+
if using_translation?
|
297
|
+
view_data = instance_eval("view.#{@view_property}", __FILE__, __LINE__)
|
298
|
+
unless @from_view_translation.has_key? view_data
|
299
|
+
raise TranslationError, "The key #{view_data.inspect} for view #{view.class} does not exist #{@from_view_translation.inspect}"
|
300
|
+
end
|
301
|
+
instance_eval("transfer[#{@transfer_property.inspect}] = @from_view_translation[view_data]", __FILE__, __LINE__)
|
302
|
+
elsif :default == @from_view_method
|
303
|
+
super
|
304
|
+
else
|
305
|
+
instance_eval("transfer[#{@transfer_property.inspect}] = view.method(@from_view_method).call(view.#{@view_property})", __FILE__, __LINE__)
|
306
|
+
end
|
307
|
+
rescue NameError => e
|
308
|
+
raise InvalidMappingError, "Either transfer[#{@transfer_property}] or view.#{@from_view_method}(#{@view_property}) is not valid.\nOriginal error: #{e}\n#{e.message}"
|
309
|
+
rescue SyntaxError, Exception => e
|
310
|
+
raise InvalidMappingError, "Error while trying to map for #{view.class}: #{to_s}\n#{e.class} - #{e}"
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
|
315
|
+
module HashMappingValidation
|
316
|
+
def properties_only?
|
317
|
+
properties = (at_least_one_property_present? and !at_least_one_method_present?)
|
318
|
+
(properties and not translate_using_present?) ? true : false
|
319
|
+
end
|
320
|
+
|
321
|
+
def both_properties_and_methods?
|
322
|
+
using = (both_properties_present? and at_least_one_method_present?)
|
323
|
+
translation = translate_using_present?
|
324
|
+
((using or translation) and not (using and translation)) ? true : false
|
325
|
+
end
|
326
|
+
|
327
|
+
def methods_only?
|
328
|
+
(!at_least_one_property_present? and at_least_one_method_present?) ? true : false
|
329
|
+
end
|
330
|
+
|
331
|
+
def translate_using_present?
|
332
|
+
!self[:translate_using].nil?
|
333
|
+
end
|
334
|
+
|
335
|
+
def both_properties_present?
|
336
|
+
!self[:view].nil? and (!self[:model].nil? or !self[:transfer].nil?)
|
337
|
+
end
|
338
|
+
|
339
|
+
def both_model_and_transfer_present?
|
340
|
+
!self[:model].nil? and !self[:transfer].nil?
|
341
|
+
end
|
342
|
+
|
343
|
+
def both_methods_present?
|
344
|
+
((!to_view_method.nil? and !from_view_method.nil?) or translate_using_present?)
|
345
|
+
end
|
346
|
+
|
347
|
+
def to_view_method_present?
|
348
|
+
!to_view_method.nil?
|
349
|
+
end
|
350
|
+
|
351
|
+
def from_view_method_present?
|
352
|
+
!from_view_method.nil?
|
353
|
+
end
|
354
|
+
|
355
|
+
def at_least_one_property_present?
|
356
|
+
!self[:view].nil? or !self[:model].nil? or !self[:transfer].nil?
|
357
|
+
end
|
358
|
+
|
359
|
+
def at_least_one_method_present?
|
360
|
+
!to_view_method.nil? or !from_view_method.nil?
|
361
|
+
end
|
362
|
+
|
363
|
+
def to_view_method
|
364
|
+
if self[:using].kind_of? Array
|
365
|
+
self[:using].first
|
366
|
+
else
|
367
|
+
self[:using]
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def from_view_method
|
372
|
+
if self[:using].kind_of? Array
|
373
|
+
self[:using][1]
|
374
|
+
else
|
375
|
+
nil
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Monkeybars
|
2
|
+
class Nesting
|
3
|
+
class << self
|
4
|
+
alias_method :__new__, :new
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.new(nesting_options = {})
|
8
|
+
nesting_options.validate_only(:sub_view, :using, :view)
|
9
|
+
nesting_options.extend Monkeybars::HashNestingValidation
|
10
|
+
|
11
|
+
if nesting_options.property_only?
|
12
|
+
PropertyNesting.__new__(nesting_options)
|
13
|
+
elsif nesting_options.methods_only?
|
14
|
+
MethodNesting.__new__(nesting_options)
|
15
|
+
else
|
16
|
+
raise InvalidNestingError, "Cannot determine nesting type with parameters #{nesting_options.inspect}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(properties)
|
21
|
+
@sub_view = properties[:sub_view]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class PropertyNesting < Nesting
|
26
|
+
def initialize(properties)
|
27
|
+
super
|
28
|
+
@view_property = properties[:view]
|
29
|
+
end
|
30
|
+
|
31
|
+
def nests_with_add?
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def nests_with_remove?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
def add(view, nested_view, nested_component, model, transfer)
|
40
|
+
instance_eval("view.#{@view_property}.add nested_component")
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove(view, nested_view, nested_component, model, transfer)
|
44
|
+
instance_eval("view.#{@view_property}.remove nested_component")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class MethodNesting < Nesting
|
49
|
+
def initialize(nesting_options)
|
50
|
+
super
|
51
|
+
@add_method, @remove_method = if nesting_options[:using].kind_of? Array
|
52
|
+
[nesting_options[:using][0], nesting_options[:using][1]]
|
53
|
+
else
|
54
|
+
[nesting_options[:using], nil]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def nests_with_add?
|
59
|
+
!@add_method.nil?
|
60
|
+
end
|
61
|
+
|
62
|
+
def nests_with_remove?
|
63
|
+
!@remove_method.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
def add(view, nested_view, nested_component, model, transfer)
|
67
|
+
#instance_eval("view.#{@add_method}(@sub_view, model, transfer)")
|
68
|
+
view.send(@add_method, nested_view, nested_component, model, transfer)
|
69
|
+
end
|
70
|
+
|
71
|
+
def remove(view, nested_view, nested_component, model, transfer)
|
72
|
+
#instance_eval("view.#{@remove_method}(@sub_view, model, transfer)")
|
73
|
+
view.send(@remove_method, nested_view, nested_component, model, transfer)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
module HashNestingValidation
|
78
|
+
def property_only?
|
79
|
+
property_present? and not (to_view_method_present? and from_view_method_present?)
|
80
|
+
end
|
81
|
+
|
82
|
+
def methods_only?
|
83
|
+
(to_view_method_present? and from_view_method_present?) and not property_present?
|
84
|
+
end
|
85
|
+
|
86
|
+
def property_present?
|
87
|
+
!self[:view].nil?
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_view_method_present?
|
91
|
+
!to_view_method.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
def from_view_method_present?
|
95
|
+
!from_view_method.nil?
|
96
|
+
end
|
97
|
+
|
98
|
+
def to_view_method
|
99
|
+
if self[:using].kind_of? Array
|
100
|
+
self[:using].first
|
101
|
+
else
|
102
|
+
self[:using]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def from_view_method
|
107
|
+
if self[:using].kind_of? Array
|
108
|
+
self[:using][1]
|
109
|
+
else
|
110
|
+
nil
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|