netzke-core 0.7.7 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. data/.travis.yml +1 -2
  2. data/CHANGELOG.md +572 -0
  3. data/LICENSE +7 -1
  4. data/README.md +345 -29
  5. data/Rakefile +3 -3
  6. data/app/controllers/netzke_controller.rb +37 -48
  7. data/config/ci/before-travis.sh +3 -4
  8. data/javascripts/base.js +86 -150
  9. data/javascripts/ext.js +180 -210
  10. data/javascripts/{core_extensions.js → js_extensions.js} +0 -0
  11. data/lib/netzke-core.rb +16 -6
  12. data/lib/netzke/base.rb +84 -107
  13. data/lib/netzke/core.rb +7 -41
  14. data/lib/netzke/core/action_config.rb +37 -0
  15. data/lib/netzke/core/actions.rb +123 -0
  16. data/lib/netzke/core/client_class.rb +252 -0
  17. data/lib/netzke/core/component_config.rb +12 -0
  18. data/lib/netzke/core/composition.rb +274 -0
  19. data/lib/netzke/core/config_to_dsl_delegator.rb +69 -0
  20. data/lib/netzke/core/configuration.rb +63 -0
  21. data/lib/netzke/core/css_config.rb +51 -0
  22. data/lib/netzke/core/dynamic_assets.rb +19 -49
  23. data/lib/netzke/{embedding.rb → core/embedding.rb} +4 -6
  24. data/lib/netzke/core/endpoint_response.rb +15 -0
  25. data/lib/netzke/core/javascript.rb +111 -0
  26. data/lib/netzke/core/panel.rb +11 -0
  27. data/lib/netzke/{plugins.rb → core/plugins.rb} +10 -5
  28. data/lib/netzke/core/railz.rb +4 -0
  29. data/lib/netzke/{railz → core/railz}/action_view_ext.rb +22 -18
  30. data/lib/netzke/core/railz/action_view_ext/ext.rb +49 -0
  31. data/lib/netzke/core/railz/controller_extensions.rb +17 -0
  32. data/lib/netzke/core/railz/engine.rb +16 -0
  33. data/lib/netzke/core/railz/routes.rb +10 -0
  34. data/lib/netzke/core/ruby_ext.rb +5 -0
  35. data/lib/netzke/core/ruby_ext/array.rb +23 -0
  36. data/lib/netzke/core/ruby_ext/hash.rb +47 -0
  37. data/lib/netzke/{core_ext → core/ruby_ext}/string.rb +2 -7
  38. data/lib/netzke/core/ruby_ext/symbol.rb +13 -0
  39. data/lib/netzke/{core_ext → core/ruby_ext}/time_with_zone.rb +0 -0
  40. data/lib/netzke/core/services.rb +130 -0
  41. data/lib/netzke/core/session.rb +15 -19
  42. data/lib/netzke/core/state.rb +40 -0
  43. data/lib/netzke/core/stylesheets.rb +48 -0
  44. data/lib/netzke/core/version.rb +2 -2
  45. data/lib/netzke/plugin.rb +8 -11
  46. data/netzke-core.gemspec +69 -59
  47. data/test/core_test_app/Gemfile +2 -20
  48. data/test/core_test_app/Gemfile.lock +65 -74
  49. data/test/core_test_app/app/components/card_component_loader.rb +4 -4
  50. data/test/core_test_app/app/components/component_loader.rb +40 -120
  51. data/test/core_test_app/app/components/component_loader/javascripts/component_loader.js +49 -0
  52. data/test/core_test_app/app/components/component_with_actions.rb +61 -47
  53. data/test/core_test_app/app/components/component_with_custom_css.rb +8 -5
  54. data/test/core_test_app/app/components/component_with_js_mixin.rb +11 -5
  55. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_one.js +1 -1
  56. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_two.js +1 -1
  57. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/method_set_one.js +1 -1
  58. data/test/core_test_app/app/components/component_with_nested_through.rb +2 -2
  59. data/test/core_test_app/app/components/component_with_prebuilt_toolbar_control.rb +12 -0
  60. data/test/core_test_app/app/components/component_with_prebuilt_toolbar_control/javascripts/component_with_prebuilt_toolbar_control.js +12 -0
  61. data/test/core_test_app/app/components/component_with_required_js.rb +24 -0
  62. data/test/core_test_app/app/components/configurable_on_class_level.rb +8 -0
  63. data/test/core_test_app/app/components/dsl_delegated_properties.rb +4 -0
  64. data/test/core_test_app/app/components/dsl_delegated_properties_base.rb +5 -0
  65. data/test/core_test_app/app/components/dynamic_tab_panel/javascripts/dynamic_tab_panel.js +2 -2
  66. data/test/core_test_app/app/components/ext_direct/composite.rb +32 -33
  67. data/test/core_test_app/app/components/ext_direct/details.rb +2 -4
  68. data/test/core_test_app/app/components/ext_direct/selector.rb +20 -22
  69. data/test/core_test_app/app/components/ext_direct/statistics.rb +2 -4
  70. data/test/core_test_app/app/components/extended_component_with_actions.rb +7 -3
  71. data/test/core_test_app/app/components/extended_component_with_js_mixin.rb +7 -4
  72. data/test/core_test_app/app/components/extended_component_with_js_mixin/javascripts/some_method_set.js +1 -1
  73. data/test/core_test_app/app/components/extended_server_caller.rb +20 -14
  74. data/test/core_test_app/app/components/hello_world.rb +23 -0
  75. data/test/core_test_app/app/components/hello_world/javascripts/hello_world.js +12 -0
  76. data/test/core_test_app/app/components/included.js +2 -2
  77. data/test/core_test_app/app/components/kinda_complex_component.rb +1 -3
  78. data/test/core_test_app/app/components/kinda_complex_component/basic_stuff.rb +15 -17
  79. data/test/core_test_app/app/components/kinda_complex_component/extra_stuff.rb +4 -5
  80. data/test/core_test_app/app/components/loader_of_component_with_custom_css.rb +14 -5
  81. data/test/core_test_app/app/components/localized_panel.rb +23 -25
  82. data/test/core_test_app/app/components/multipane_component_loader.rb +19 -20
  83. data/test/core_test_app/app/components/nested_component.rb +4 -5
  84. data/test/core_test_app/app/components/panel_with_plugin.rb +8 -3
  85. data/test/core_test_app/app/components/panel_with_tools.rb +15 -14
  86. data/test/core_test_app/app/components/plugin_with_components.rb +20 -12
  87. data/test/core_test_app/app/components/scoped_components/deep_scoped_components/some_deep_scoped_component.rb +5 -2
  88. data/test/core_test_app/app/components/scoped_components/extended_scoped_component.rb +5 -2
  89. data/test/core_test_app/app/components/scoped_components/some_scoped_component.rb +5 -2
  90. data/test/core_test_app/app/components/server_caller.rb +39 -17
  91. data/test/core_test_app/app/components/server_caller/javascripts/server_caller.js +42 -0
  92. data/test/core_test_app/app/components/server_counter.rb +18 -82
  93. data/test/core_test_app/app/components/server_counter/javascripts/server_counter.js +53 -0
  94. data/test/core_test_app/app/components/simple_authentication_component.rb +46 -0
  95. data/test/core_test_app/app/components/simple_component.rb +8 -3
  96. data/test/core_test_app/app/components/simple_composite.rb +12 -0
  97. data/test/core_test_app/app/components/simple_form_with_file_upload.rb +49 -0
  98. data/test/core_test_app/app/components/simple_panel.rb +2 -2
  99. data/test/core_test_app/app/components/simple_tab_panel.rb +24 -3
  100. data/test/core_test_app/app/components/simple_window.rb +4 -2
  101. data/test/core_test_app/app/components/some_composite.rb +77 -48
  102. data/test/core_test_app/app/components/some_plugin.rb +31 -30
  103. data/test/core_test_app/app/components/stateful_component.rb +46 -0
  104. data/test/core_test_app/app/components/stateful_component_with_shared_state.rb +11 -0
  105. data/test/core_test_app/app/components/window_with_simple_component.rb +14 -0
  106. data/test/core_test_app/app/views/layouts/application.html.erb +1 -1
  107. data/test/core_test_app/app/views/simple_rails/multiple_nested.html.erb +7 -19
  108. data/test/core_test_app/app/views/simple_rails/panel.html.erb +1 -0
  109. data/test/core_test_app/config/database.yml.travis +3 -5
  110. data/test/core_test_app/config/environments/production.rb +1 -1
  111. data/test/core_test_app/config/initializers/netzke.rb +3 -1
  112. data/test/core_test_app/config/locales/en.yml +9 -4
  113. data/test/core_test_app/config/locales/es.yml +4 -2
  114. data/test/core_test_app/config/routes.rb +2 -8
  115. data/test/core_test_app/db/schema.rb +3 -11
  116. data/test/core_test_app/features/actions_and_tools.feature +1 -0
  117. data/test/core_test_app/features/client-server.feature +7 -0
  118. data/test/core_test_app/features/component_loader.feature +13 -13
  119. data/test/core_test_app/features/composition.feature +14 -0
  120. data/test/core_test_app/features/config_to_dsl_delegation.feature +10 -0
  121. data/test/core_test_app/features/file_inclusion.feature +1 -1
  122. data/test/core_test_app/features/i18n.feature +4 -4
  123. data/test/core_test_app/features/js_include.feature +1 -1
  124. data/test/core_test_app/features/persistence.feature +21 -5
  125. data/test/core_test_app/features/step_definitions/generic_steps.rb +14 -0
  126. data/test/core_test_app/features/support/paths.rb +0 -3
  127. data/test/core_test_app/public/images/icons/accept.png +0 -0
  128. data/test/core_test_app/public/images/icons/anchor.png +0 -0
  129. data/test/core_test_app/public/images/icons/tick.png +0 -0
  130. data/test/core_test_app/spec/action_config_spec.rb +15 -0
  131. data/test/core_test_app/spec/{component/actions_spec.rb → actions_spec.rb} +38 -36
  132. data/test/core_test_app/spec/base_spec.rb +35 -0
  133. data/test/core_test_app/spec/client_class_spec.rb +17 -0
  134. data/test/core_test_app/spec/component +0 -0
  135. data/test/core_test_app/spec/composition_spec.rb +118 -0
  136. data/test/core_test_app/spec/core_ext_spec.rb +3 -14
  137. data/test/core_test_app/spec/endpoint_response_spec.rb +17 -0
  138. data/test/core_test_app/spec/javascript_spec.rb +33 -0
  139. data/test/core_test_app/spec/js_class_config_scope.rb +37 -0
  140. data/test/core_test_app/spec/panel_spec.rb +11 -0
  141. data/test/core_test_app/spec/services_spec.rb +16 -0
  142. data/test/core_test_app/spec/state_spec.rb +20 -0
  143. data/test/unit/core_ext_test.rb +0 -53
  144. data/test/unit/netzke_core_test.rb +11 -11
  145. metadata +76 -62
  146. data/CHANGELOG.rdoc +0 -325
  147. data/javascripts/touch.js +0 -58
  148. data/lib/netzke/actions.rb +0 -107
  149. data/lib/netzke/composition.rb +0 -224
  150. data/lib/netzke/config_to_dsl_delegator.rb +0 -43
  151. data/lib/netzke/configuration.rb +0 -195
  152. data/lib/netzke/core/masquerading.rb +0 -34
  153. data/lib/netzke/core_ext.rb +0 -6
  154. data/lib/netzke/core_ext/array.rb +0 -30
  155. data/lib/netzke/core_ext/hash.rb +0 -86
  156. data/lib/netzke/core_ext/symbol.rb +0 -21
  157. data/lib/netzke/ext_component.rb +0 -25
  158. data/lib/netzke/inheritance.rb +0 -31
  159. data/lib/netzke/javascript.rb +0 -382
  160. data/lib/netzke/javascript/scopes.rb +0 -39
  161. data/lib/netzke/railz.rb +0 -4
  162. data/lib/netzke/railz/action_view_ext/ext.rb +0 -64
  163. data/lib/netzke/railz/action_view_ext/touch.rb +0 -52
  164. data/lib/netzke/railz/controller_extensions.rb +0 -33
  165. data/lib/netzke/railz/engine.rb +0 -48
  166. data/lib/netzke/railz/routes.rb +0 -7
  167. data/lib/netzke/services.rb +0 -101
  168. data/lib/netzke/session.rb +0 -54
  169. data/lib/netzke/state.rb +0 -91
  170. data/lib/netzke/stylesheets.rb +0 -65
  171. data/test/core_test_app/app/components/component_with_included_js.rb +0 -16
  172. data/test/core_test_app/app/components/component_with_session_persistence.rb +0 -35
  173. data/test/core_test_app/app/components/deprecated/server_caller.rb +0 -20
  174. data/test/core_test_app/app/components/dynamic_tab_panel.rb +0 -19
  175. data/test/core_test_app/app/components/hello_world_component.rb +0 -31
  176. data/test/core_test_app/app/components/touch/hello_world_component.rb +0 -25
  177. data/test/core_test_app/app/components/touch/server_caller.rb +0 -28
  178. data/test/core_test_app/app/components/touch/simple_carousel.rb +0 -17
  179. data/test/core_test_app/app/controllers/touch_controller.rb +0 -6
  180. data/test/core_test_app/app/helpers/touch_helper.rb +0 -2
  181. data/test/core_test_app/app/views/layouts/touch.html.erb +0 -13
  182. data/test/core_test_app/db/migrate/20110110132720_create_netzke_component_states.rb +0 -20
  183. data/test/core_test_app/features/step_definitions/touch_steps.rb +0 -3
  184. data/test/core_test_app/features/touch.feature +0 -10
  185. data/test/core_test_app/gemfiles/rails3_1.gemfile +0 -16
  186. data/test/core_test_app/gemfiles/rails3_2.gemfile +0 -16
  187. data/test/core_test_app/spec/component/base_spec.rb +0 -36
  188. data/test/core_test_app/spec/component/component_spec.rb +0 -20
  189. data/test/core_test_app/spec/component/composition_spec.rb +0 -132
  190. data/test/core_test_app/spec/component/configuration_spec.rb +0 -61
  191. data/test/core_test_app/spec/component/javascript_spec.rb +0 -16
  192. data/test/core_test_app/spec/component/state_spec.rb +0 -18
@@ -1,224 +0,0 @@
1
- module Netzke
2
- # This module takes care of components composition.
3
- #
4
- # You can define a nested component by calling the +component+ class method:
5
- #
6
- # component :users, :data_class => "GridPanel", :model => "User"
7
- #
8
- # The method also accepts a block in case you want access to the component's instance:
9
- #
10
- # component :books do
11
- # {:data_class => "Book", :title => build_title}
12
- # end
13
- #
14
- # To override a component, define a method {component_name}_component, e.g.:
15
- #
16
- # def books_component
17
- # super.merge(:title => "Modified Title")
18
- # end
19
- module Composition
20
- extend ActiveSupport::Concern
21
-
22
- COMPONENT_METHOD_NAME = "%s_component"
23
-
24
- included do
25
-
26
- # Returns registered components
27
- class_attribute :registered_components
28
- self.registered_components = []
29
-
30
- # Loads a component on browser's request. Every Netzke component gets this endpoint.
31
- # <tt>params</tt> should contain:
32
- # * <tt>:cache</tt> - an array of component classes cached at the browser
33
- # * <tt>:id</tt> - reference to the component
34
- # * <tt>:container</tt> - Ext id of the container where in which the component will be rendered
35
- endpoint :deliver_component do |params|
36
- cache = params[:cache].split(",") # array of cached xtypes
37
- component_name = params[:name].underscore.to_sym
38
- component = components[component_name] && component_instance(component_name)
39
-
40
- if component
41
- # inform the component that it's being loaded
42
- component.before_load
43
-
44
- [{
45
- :eval_js => component.js_missing_code(cache),
46
- :eval_css => component.css_missing_code(cache)
47
- }, {
48
- :component_delivered => component.js_config
49
- }]
50
- else
51
- {:component_delivery_failed => {:component_name => component_name, :msg => "Couldn't load component '#{component_name}'"}}
52
- end
53
- end
54
-
55
- end # included
56
-
57
- module ClassMethods
58
-
59
- # Defines a nested component.
60
- def component(name, config = {}, &block)
61
- register_component(name)
62
- config = config.dup
63
- config[:class_name] ||= name.to_s.camelize
64
- config[:name] = name.to_s
65
- method_name = COMPONENT_METHOD_NAME % name
66
-
67
- if block_given?
68
- define_method(method_name, &block)
69
- else
70
- if superclass.instance_methods.map(&:to_s).include?(method_name)
71
- define_method(method_name) do
72
- super().merge(config)
73
- end
74
- else
75
- define_method(method_name) do
76
- config
77
- end
78
- end
79
- end
80
- end
81
-
82
- # DEPRECATED in favor of Symbol#component
83
- # Component's js config used when embedding components as Container's items
84
- # (see some_composite.rb for an example)
85
- def js_component(name, config = {})
86
- ::ActiveSupport::Deprecation.warn("Using js_component is deprecated. Use Symbol#component instead", caller)
87
- config.merge(:component => name)
88
- end
89
-
90
- # Register a component
91
- def register_component(name)
92
- self.registered_components |= [name]
93
- end
94
-
95
- end
96
-
97
- def items #:nodoc:
98
- @items_with_normalized_components
99
- end
100
-
101
- # DEPRECATED in favor of Base.component
102
- def initial_components
103
- {}
104
- end
105
-
106
- # All components for this instance, which includes components defined on class level, and components detected in :items
107
- def components
108
- @components ||= self.class.registered_components.inject({}){ |res, name| res.merge(name.to_sym => send(COMPONENT_METHOD_NAME % name)) }.merge(config[:components] || {})
109
- end
110
-
111
- def eager_loaded_components
112
- components.reject{|k,v| v[:lazy_loading]}
113
- end
114
-
115
- # DEPRECATED
116
- def add_component(aggr)
117
- components.merge!(aggr)
118
- end
119
-
120
- # DEPRECATED
121
- def remove_component(aggr)
122
- if config[:persistent_config]
123
- persistence_manager_class.delete_all_for_component("#{global_id}__#{aggr}")
124
- end
125
- components[aggr] = nil
126
- end
127
-
128
- # Called when the method_missing tries to processes a non-existing component
129
- def component_missing(aggr)
130
- flash :error => "Unknown component #{aggr} for component #{name}"
131
- {:feedback => @flash}.to_nifty_json
132
- end
133
-
134
- # Recursively instantiates a component based on its "path": e.g. if we have component :component1 which in its turn has component :component2, the path to the latter would be "component1__component2"
135
- # TODO: strong_config should probably be thrown away, and is not taken into account when caching the results
136
- def component_instance(name, strong_config = {})
137
- @component_instance_cache ||= {}
138
- @component_instance_cache[name] ||= begin
139
- composite = self
140
- name.to_s.split('__').each do |cmp|
141
- cmp = cmp.to_sym
142
-
143
- component_config = composite.components[cmp]
144
- raise ArgumentError, "No child component '#{cmp}' defined for component '#{composite.global_id}'" if component_config.nil?
145
-
146
- component_class_name = component_config[:class_name]
147
- raise ArgumentError, "No class_name specified for component #{cmp} of #{composite.global_id}" if component_class_name.nil?
148
-
149
- component_class = constantize_class_name(component_class_name)
150
- raise ArgumentError, "Unknown constant #{component_class_name}" if component_class.nil?
151
-
152
- instance_config = weak_children_config.merge(component_config).merge(strong_config).merge(:name => cmp)
153
-
154
- composite = component_class.new(instance_config, composite) # params: config, parent
155
- end
156
- composite
157
- end
158
- end
159
-
160
- # All components that we depend on (used to render all necessary JavaScript and stylesheets)
161
- def dependency_classes
162
- res = []
163
-
164
- eager_loaded_components.keys.each do |aggr|
165
- res += component_instance(aggr).dependency_classes
166
- end
167
-
168
- res += self.class.class_ancestors
169
-
170
- res << self.class
171
- res.uniq
172
- end
173
-
174
- # DEPRECATED
175
- def js_component(*args)
176
- self.class.js_component(*args)
177
- end
178
-
179
- # Returns global id of a component in the hierarchy, based on passed reference that follows
180
- # the double-underscore notation. Referring to "parent" is allowed. If going to far up the hierarchy will
181
- # result in <tt>nil</tt>, while referring to a non-existent component will simply provide an erroneous ID.
182
- # Example:
183
- # <tt>parent__parent__child__subchild</tt> will traverse the hierarchy 2 levels up, then going down to "child",
184
- # and further to "subchild". If such a component exists in the hierarchy, its global id will be returned, otherwise
185
- # <tt>nil</tt> will be returned.
186
- def global_id_by_reference(ref)
187
- ref = ref.to_s
188
- return parent && parent.global_id if ref == "parent"
189
- substr = ref.sub(/^parent__/, "")
190
- if substr == ref # there's no "parent__" in the beginning
191
- return global_id + "__" + ref
192
- else
193
- return parent.global_id_by_reference(substr)
194
- end
195
- end
196
-
197
- protected
198
-
199
- def normalize_components(items) #:nodoc:
200
- @component_index ||= 0
201
- @items_with_normalized_components = items.each_with_index.map do |item, i|
202
- if is_component_config?(item)
203
- component_name = item[:name] || :"netzke_#{@component_index}" # default name/item_id for child components
204
- @component_index += 1
205
- self.class.component(component_name.to_sym, item)
206
- component_name.to_sym.component # replace current item with a reference to component
207
- elsif item.is_a?(Hash)
208
- item[:items].is_a?(Array) ? item.merge(:items => normalize_components(item[:items])) : item
209
- else
210
- item
211
- end
212
- end
213
- end
214
-
215
- def normalize_components_in_items #:nodoc:
216
- normalize_components(config[:items]) if config[:items]
217
- end
218
-
219
- def is_component_config?(c) #:nodoc:
220
- !!(c.is_a?(Hash) && c[:class_name])
221
- end
222
-
223
- end
224
- end
@@ -1,43 +0,0 @@
1
- module Netzke
2
- # This module allows delegating the configuration options for a component into the level of the component's class.
3
- # As an example, let's take the :title option understood by any Ext.panel.Panel-derived component. Netzke::Base calls:
4
- #
5
- # delegates_to_dsl :title
6
- #
7
- # which provides any child class with a DSL method `title` which can be used like this:
8
- #
9
- # class MyComponent < Netzke::Base
10
- # title "My cool component"
11
- # end
12
- #
13
- # This will provide for :title => "My cool component" being a default option for MyComponent's instances.
14
- #
15
- # This is very handy when a frequently-inherited class implements some common option. Another example would be the :model option in Basepack::Grid/FormPanel. This way the child class will not need to mess up with the `default_config` method if all it needs is specify that default option.
16
- module ConfigToDslDelegator
17
- extend ActiveSupport::Concern
18
-
19
- included do
20
- class_attribute :delegated_options
21
- self.delegated_options = []
22
- end
23
-
24
- module ClassMethods
25
- # Delegates specified configuration options to the class level. See ConfigToDslDelegator.
26
- def delegates_to_dsl(*option_names)
27
- self.delegated_options |= option_names
28
- end
29
-
30
- def inherited(inherited_class) # :nodoc:
31
- super
32
-
33
- properties = self.delegated_options
34
- properties.each do |property|
35
- inherited_class.class.send(:define_method, property, lambda { |value|
36
- default_config = self.default_config_attr.dup
37
- self.default_config_attr = default_config.merge(property.to_sym => value)
38
- })
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,195 +0,0 @@
1
- module Netzke
2
- # Handles all the intricate matters of component configuration.
3
- # TODO: simplify!
4
- module Configuration
5
- extend ActiveSupport::Concern
6
-
7
- CONFIGURATION_LEVELS = [:default, :initial, :independent, :session, :final]
8
-
9
- included do
10
- CONFIGURATION_LEVELS.each do |level|
11
- define_method("weak_#{level}_options"){ {} }
12
- end
13
-
14
- class_attribute :default_config_attr
15
- self.default_config_attr = {}
16
-
17
- end
18
-
19
- module ClassMethods
20
- def setup
21
- yield self
22
- end
23
-
24
- # Config options that should not go to the client side
25
- def server_side_config_options
26
- [:lazy_loading, :class_name, :components]
27
- end
28
-
29
- def config(*args, &block)
30
- level = args.first.is_a?(Symbol) ? args.first : :final
31
- config_hash = args.last.is_a?(Hash) && args.last
32
- raise ArgumentError, "Config hash or block required" if !block_given? && !config_hash
33
- if block_given?
34
- define_method(:"weak_#{level}_options", &block)
35
- else
36
- define_method(:"weak_#{level}_options") do
37
- config_hash
38
- end
39
- end
40
- end
41
-
42
- # Used to define class-level configuration options for a component, e.g.:
43
- #
44
- # class Netzke::Basepack::GridPanel < Netzke::Base
45
- # class_config_option :rows_reordering_available, true
46
- # ...
47
- # end
48
- #
49
- # This can later be set in the application configuration:
50
- #
51
- # module RailsApp
52
- # class Application < Rails::Application
53
- # config.netzke.basepack.grid_panel.rows_reordering_available = false
54
- # ...
55
- # end
56
- # end
57
- #
58
- # Configuration options can be accessed as class attributes:
59
- #
60
- # Netzke::Basepack::GridPanel.rows_reordering_available # => false
61
- def class_config_option(name, default_value)
62
- value = if app_level_config.has_key?(name.to_sym)
63
- if app_level_config[name.to_sym].is_a?(Hash) && default_value.is_a?(Hash)
64
- default_value.deep_merge(app_level_config[name.to_sym])
65
- else
66
- app_level_config[name.to_sym]
67
- end
68
- else
69
- default_value
70
- end
71
-
72
- class_attribute(name.to_sym)
73
- self.send("#{name}=", value)
74
- end
75
-
76
- protected
77
-
78
- def app_level_config
79
- @app_level_config ||= class_ancestors.inject({}) do |r,klass|
80
- r.deep_merge(klass.app_level_config_excluding_parents)
81
- end
82
- end
83
-
84
- def app_level_config_excluding_parents
85
- path_parts = name.split("::").map(&:underscore)[1..-1]
86
- if path_parts.present?
87
- path_parts.inject(Netzke::Core.config) do |r,part|
88
- r.send(part)
89
- end
90
- else
91
- {}
92
- end
93
- end
94
-
95
- end
96
-
97
- # Default config - before applying any passed configuration
98
- def default_config
99
- @default_config ||= {}.merge(weak_default_options).merge(self.class.default_instance_config).merge(self.default_config_attr)
100
- end
101
-
102
- # Static, hardcoded config. Consists of default values merged with config that was passed during instantiation
103
- def initial_config
104
- @initial_config ||= default_config.merge(weak_initial_options).merge(@passed_config)
105
- end
106
-
107
- # Config that is not overridden by parents and sessions
108
- def independent_config
109
- @independent_config ||= initial_config.merge(weak_independent_options).merge(initial_config[:persistence] ? persistent_options : {})
110
- end
111
-
112
- def session_config
113
- @session_config ||= independent_config.merge(weak_session_options).merge(session_options)
114
- end
115
-
116
- # Last level config, overridden only by ineritance
117
- def final_config
118
- @strong_config ||= session_config.merge(weak_final_options).merge(strong_parent_config)
119
- end
120
-
121
- def configuration
122
- final_config
123
- end
124
-
125
- # Resulting config that takes into account all possible ways to configure a component. *Read only*.
126
- # Translates into something like this:
127
- #
128
- # default_config.
129
- # deep_merge(@passed_config).
130
- # deep_merge(persistent_options).
131
- # deep_merge(strong_parent_config).
132
- # deep_merge(strong_session_config)
133
- #
134
- # Moved out to a separate method in order to provide for easy caching.
135
- # *Do not override this method*, use +Base.config+ instead.
136
- def config
137
- @config ||= configuration
138
- end
139
-
140
- def flat_config(key = nil)
141
- fc = config.flatten_with_type
142
- key.nil? ? fc : fc.select{ |c| c[:name] == key.to_sym }.first.try(:value)
143
- end
144
-
145
- def strong_parent_config
146
- @strong_parent_config ||= parent.nil? ? {} : parent.strong_children_config
147
- end
148
-
149
- def flat_independent_config(key = nil)
150
- fc = independent_config.flatten_with_type
151
- key.nil? ? fc : fc.select{ |c| c[:name] == key.to_sym }.first.try(:value)
152
- end
153
-
154
- def flat_default_config(key = nil)
155
- fc = default_config.flatten_with_type
156
- key.nil? ? fc : fc.select{ |c| c[:name] == key.to_sym }.first.try(:value)
157
- end
158
-
159
- def flat_initial_config(key = nil)
160
- fc = initial_config.flatten_with_type
161
- key.nil? ? fc : fc.select{ |c| c[:name] == key.to_sym }.first.try(:value)
162
- end
163
-
164
- # Like normal config, but stored in session
165
- # def weak_session_config
166
- # component_session[:weak_session_config] ||= {}
167
- # end
168
- #
169
- # def strong_session_config
170
- # component_session[:strong_session_config] ||= {}
171
- # end
172
-
173
-
174
-
175
- # configuration of all children will get deep_merge'd with strong_children_config
176
- # def strong_children_config= (c)
177
- # @strong_children_config = c
178
- # end
179
-
180
- # This config will be picked up by all the descendants
181
- def strong_children_config
182
- @strong_children_config ||= parent.nil? ? {} : parent.strong_children_config
183
- end
184
-
185
- # configuration of all children will get reverse_deep_merge'd with weak_children_config
186
- # def weak_children_config= (c)
187
- # @weak_children_config = c
188
- # end
189
-
190
- def weak_children_config
191
- @weak_children_config ||= {}
192
- end
193
-
194
- end
195
- end