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
@@ -0,0 +1,69 @@
1
+ module Netzke::Core
2
+ # This module can be included in a component class to allows delegating the configuration options for a component into the level of the component's class.
3
+ # For example:
4
+ #
5
+ # class SomeComponentBase < Netzke::Base
6
+ # delegates_to_dsl :title, :html
7
+ # end
8
+ #
9
+ # This will provide its children with class (DSL) methods +title+ and +html+:
10
+ #
11
+ # class SomeComponent < SomeComponentBase
12
+ # title "Some component"
13
+ # html "HTML set in DSL"
14
+ # end
15
+ #
16
+ # ... which would be equivalent to:
17
+ #
18
+ # class SomeComponent < SomeComponentBase
19
+ # def configure(c)
20
+ # c.title = "Some component"
21
+ # c.html = "HTML set in DSL"
22
+ # super
23
+ # end
24
+ # end
25
+ #
26
+ # This may be handy when a frequently-inherited class implements some common options.
27
+ module ConfigToDslDelegator
28
+ extend ActiveSupport::Concern
29
+
30
+ included do
31
+ class_attribute :delegated_options
32
+ self.delegated_options = []
33
+
34
+ class_attribute :delegated_defaults
35
+ self.delegated_defaults = {}
36
+
37
+ delegated_options.each do |property|
38
+ inherited_class.class.send(:define_method, property, lambda { |value|
39
+ self.delegated_defaults = self.delegated_defaults.dup if self.superclass.respond_to?(:delegated_defaults) && self.delegated_defaults == self.superclass.delegated_defaults
40
+ self.delegated_defaults[property.to_sym] = value
41
+ })
42
+ end
43
+ end
44
+
45
+ def configure(c)
46
+ c.merge! delegated_defaults
47
+ super
48
+ end
49
+
50
+ module ClassMethods
51
+ # Delegates specified configuration options to the class level
52
+ def delegates_to_dsl(*option_names)
53
+ self.delegated_options |= option_names
54
+ end
55
+
56
+ def inherited(inherited_class)
57
+ super
58
+
59
+ properties = self.delegated_options
60
+ properties.each do |property|
61
+ inherited_class.class.send(:define_method, property, lambda { |value|
62
+ self.delegated_defaults = self.delegated_defaults.dup if self.superclass.respond_to?(:delegated_defaults) && self.delegated_defaults == self.superclass.delegated_defaults
63
+ self.delegated_defaults[property.to_sym] = value
64
+ })
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,63 @@
1
+ module Netzke::Core
2
+ # Components can implement class-level config options by using `class_attribute`, e.g.:
3
+ #
4
+ # class MyComponent < Netzke::Base
5
+ # class_attribute :title
6
+ # self.title = "Title for all descendants of MyComponent"
7
+ #
8
+ # js_configure do |c|
9
+ # c.title = title
10
+ # end
11
+ # end
12
+ #
13
+ # Then before using MyComponent (e.g. in Rails' initializers), you can configure it like this:
14
+ #
15
+ # MyComponent.title = "Better title"
16
+ #
17
+ # Alternatively, you can use the `Base.setup` method:
18
+ #
19
+ # MyComponent.setup do |config|
20
+ # config.title = "Better title"
21
+ # end
22
+ module Configuration
23
+ extend ActiveSupport::Concern
24
+
25
+ # Use to configure a component on the class level, for example:
26
+ #
27
+ # MyComponent.setup do |config|
28
+ # config.enable_awesome_feature = true
29
+ # end
30
+ module ClassMethods
31
+ def setup
32
+ yield self
33
+ end
34
+
35
+ # An array of server class config options that should not be passed to the client class. Can be overridden.
36
+ def server_side_config_options
37
+ [:eager_loading, :klass]
38
+ end
39
+ end
40
+
41
+ # Override to auto-configure components. Example:
42
+ #
43
+ # class BookGrid < Netzke::Basepack::Grid
44
+ # def configure(c)
45
+ # super
46
+ # c.model = "Book"
47
+ # end
48
+ # end
49
+ def configure(c)
50
+ # passed config
51
+ c.merge!(@passed_config)
52
+ end
53
+
54
+ # Complete server class configuration. Can be accessed from within endpoint, component, and action blocks, as well as any other instance method, for example:
55
+ #
56
+ # action :do_something do |c|
57
+ # c.title = "Do it for #{config.title}"
58
+ # end
59
+ def config
60
+ @config ||= ActiveSupport::OrderedOptions.new
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,51 @@
1
+ module Netzke
2
+ module Core
3
+ # This class is responsible of assemblage of stylesheet dependencies. It is passed as block parameter to the +css_configure+ DSL method:
4
+ #
5
+ # class MyComponent < Netzke::Base
6
+ # css_configure do |c|
7
+ # c.require :extra_styles
8
+ # end
9
+ # end
10
+ class CssConfig
11
+
12
+ attr_accessor :required_files
13
+
14
+ def initialize(klass)
15
+ @klass = klass
16
+ @required_files = []
17
+ end
18
+
19
+ # Use it to specify extra stylesheet files to be loaded for the component.
20
+ #
21
+ # It may accept one or more symbols or strings.
22
+ #
23
+ # Symbols will be expanded following a convention, e.g.:
24
+ #
25
+ # class MyComponent < Netzke::Base
26
+ # css_configure do |c|
27
+ # c.require :some_styles
28
+ # end
29
+ # end
30
+ #
31
+ # This will "require" a stylesheet file +{component_location}/my_component/stylesheets/some_styles.js+
32
+ #
33
+ # Strings will be interpreted as full paths to the required JavaScript file:
34
+ #
35
+ # css_configure do |c|
36
+ # c.require "#{File.dirname(__FILE__)}/my_component/one.css", "#{File.dirname(__FILE__)}/my_component/two.css"
37
+ # end
38
+ def require(*args)
39
+ callr = caller.first
40
+ @required_files |= args.map{ |a| a.is_a?(Symbol) ? expand_css_require_path(a, callr) : a }
41
+ end
42
+
43
+ private
44
+
45
+ def expand_css_require_path(sym, callr)
46
+ %Q(#{callr.split(".rb:").first}/stylesheets/#{sym}.css)
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -2,34 +2,6 @@ module Netzke
2
2
  module Core
3
3
  module DynamicAssets
4
4
  class << self
5
- def touch_js
6
- res = initial_dynamic_javascript << "\n"
7
-
8
- include_base_js(res)
9
- # Touch-specific JavaScript
10
- res << File.new(File.expand_path("../../../../javascripts/touch.js", __FILE__)).read
11
-
12
- # Pluggable JavaScript (may be used by other Netzke-powered gems like netzke-basepack)
13
- Netzke::Core.touch_javascripts.each do |path|
14
- f = File.new(path)
15
- res << f.read
16
- end
17
-
18
- defined?(::Rails) && ::Rails.env.production? ? res.strip_js_comments : res
19
- end
20
-
21
- def touch_css
22
- res = File.new(File.expand_path("../../../../stylesheets/core.css", __FILE__)).read
23
-
24
- # Pluggable stylesheets (may be used by other Netzke-powered gems like netzke-basepack)
25
- Netzke::Core.touch_stylesheets.each do |path|
26
- f = File.new(path)
27
- res << f.read
28
- end
29
-
30
- res
31
- end
32
-
33
5
  def ext_js(form_authenticity_token)
34
6
  res = initial_dynamic_javascript(form_authenticity_token) << "\n"
35
7
 
@@ -59,34 +31,32 @@ module Netzke
59
31
  res
60
32
  end
61
33
 
62
- protected
34
+ private
63
35
 
64
- # Generates initial javascript code that is dependent on Rails settings
65
- def initial_dynamic_javascript(form_authenticity_token)
66
- res = []
67
- res << %(Ext.Ajax.extraParams = {authenticity_token: '#{form_authenticity_token}'}; // Rails' forgery protection)
68
- res << %{Ext.ns('Netzke');}
69
- res << %{Ext.ns('Netzke.core');}
70
- res << %{Netzke.RelativeUrlRoot = '#{ActionController::Base.config.relative_url_root}';}
71
- res << %{Netzke.RelativeExtUrl = '#{ActionController::Base.config.relative_url_root}#{Netzke::Core.ext_uri}';}
36
+ # Generates initial javascript code that is dependent on Rails settings
37
+ def initial_dynamic_javascript(form_authenticity_token)
38
+ res = []
39
+ res << %(Ext.Ajax.extraParams = {authenticity_token: '#{form_authenticity_token}'}; // Rails' forgery protection)
40
+ res << %{Ext.ns('Netzke');}
41
+ res << %{Ext.ns('Netzke.core');}
42
+ res << %{Netzke.RelativeUrlRoot = '#{ActionController::Base.config.relative_url_root}';}
43
+ res << %{Netzke.ControllerUrl = '#{ActionController::Base.config.relative_url_root}#{Rails.application.routes.url_helpers.netzke_path('')}';}
44
+ res << %{Netzke.RelativeExtUrl = '#{ActionController::Base.config.relative_url_root}#{Netzke::Core.ext_uri}';}
72
45
 
73
- res << %{Netzke.core.directMaxRetries = #{Netzke::Core.js_direct_max_retries};}
46
+ res << %{Netzke.core.directMaxRetries = #{Netzke::Core.js_direct_max_retries};}
74
47
 
75
- res.join("\n")
76
- end
77
-
78
- def include_base_js(arry)
79
- # JavaScript extensions
80
- arry << File.new(File.expand_path("../../../../javascripts/core_extensions.js", __FILE__)).read
48
+ res.join("\n")
49
+ end
81
50
 
82
- # Base Netzke component JavaScript
83
- arry << File.new(File.expand_path("../../../../javascripts/base.js", __FILE__)).read
84
- end
51
+ def include_base_js(arry)
52
+ # JavaScript extensions
53
+ arry << File.new(File.expand_path("../../../../javascripts/js_extensions.js", __FILE__)).read
85
54
 
86
- # end protected
55
+ # Base Netzke component JavaScript
56
+ arry << File.new(File.expand_path("../../../../javascripts/base.js", __FILE__)).read
57
+ end
87
58
 
88
59
  end
89
-
90
60
  end
91
61
  end
92
62
  end
@@ -1,21 +1,19 @@
1
- module Netzke
1
+ module Netzke::Core
2
2
  # The following methods are used when a component is generated stand-alone (as a part of a HTML page)
3
3
  module Embedding
4
-
5
4
  # Instantiating
6
5
  def js_component_instance
7
- %Q{Netzke.page.#{name.jsonify} = Ext.create("#{self.class.js_alias}", #{js_config.to_nifty_json});}
6
+ %Q{Netzke.page.#{name.jsonify} = Ext.create("#{self.class.js_config.class_alias}", #{js_config.to_nifty_json});}
8
7
  end
9
8
 
10
9
  # Rendering
11
10
  def js_component_render
12
- %Q{Netzke.page.#{name.jsonify}.render("#{name.to_s.split('_').join('-')}-netzke");} unless self.class.js_xtype == "netzkewindow"
11
+ %Q{Netzke.page.#{name.jsonify}.render("#{name.to_s.split('_').join('-')}-netzke");} unless self.class.js_config.xtype == "netzkewindow"
13
12
  end
14
13
 
15
14
  # Container for rendering
16
15
  def js_component_html
17
16
  %Q{<div id="#{name.to_s.split('_').join('-')}-netzke" class="netzke-component"></div>}
18
17
  end
19
-
20
18
  end
21
- end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Netzke::Core
2
+ # Represents the endpoint response at the server side.
3
+ # An instance of it is passed as the second parameter to the +endpoint+ block.
4
+ class EndpointResponse < ::Hash
5
+ def method_missing(name, *params)
6
+ if name.to_s =~ /(.+)=$/
7
+ self[$1.to_sym] = params.first
8
+ else
9
+ self[name] = self.class.new if self[name].nil?
10
+ self[name] = params if params.present?
11
+ self[name]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,111 @@
1
+ module Netzke::Core
2
+ # Client class definition and instantiation.
3
+ #
4
+ # == JavaScript instance methods
5
+ #
6
+ # The following public JavaScript methods are defined on (mixed-in into) all Netzke components (for detailed documentation on them see the inline documentation in javascript/base.js and javascript/ext.js files):
7
+ # * netzkeLoadComponent - dynamically loads a child Netzke component
8
+ # * netzkeInstantiateComponent - instantiates and returns a Netzke component by its item_id
9
+ # * netzkeFeedback - shows a feedback message
10
+ # * componentNotInSession - gets called when the session that the component is defined in gets expired. Override it to do whatever is appropriate.
11
+ module Javascript
12
+ extend ActiveSupport::Concern
13
+
14
+ module ClassMethods
15
+ # Configures JS class
16
+ # Example:
17
+ #
18
+ # js_configure do |c|
19
+ # # c is an instance of ClientClass
20
+ # c.title = "My title"
21
+ # c.mixin
22
+ # c.require :extra_js
23
+ # # ...etc
24
+ # end
25
+ #
26
+ # For more details see {Netzke::Core::ClientClass}
27
+ def js_configure &block
28
+ @js_configure_blocks ||= []
29
+ @js_configure_blocks << block
30
+ end
31
+
32
+ # Class-level client class config
33
+ def js_config
34
+ return @js_config if @js_config.present?
35
+ @js_config = Netzke::Core::ClientClass.new(self)
36
+ @js_config.tap do |c|
37
+ (@js_configure_blocks || []).each{|block| block.call(c)}
38
+ end
39
+ end
40
+ end
41
+
42
+ # Builds {#js_config} used for instantiating a client class. Override it when you need to extend/modify the config for the JS component intance. It's *not* being called when the *server* class is being instantiated (e.g. to process an endpoint call). With other words, it's only being called before a component is first being loaded in the browser. so, it's ok to do heavy stuf fhere, like building a tree panel nodes from the database.
43
+ def js_configure(c)
44
+ c.merge!(normalized_config)
45
+
46
+ # Unique id of the component
47
+ c.id = js_id
48
+
49
+ # Configuration for all of our non-lazy-loaded children specified here. We can refer to them in +items+ so they get instantiated by Ext.
50
+ c.netzke_components = js_components unless js_components.empty?
51
+
52
+ # Endpoints (besides the default "deliver_component" - JavaScript side already knows about it)
53
+ endpoints = self.class.endpoints.keys - [:deliver_component]
54
+
55
+ # pass them as strings, not as symbols
56
+ c.endpoints = endpoints.map(&:to_s) unless endpoints.empty?
57
+
58
+ # Include our xtype
59
+ c.xtype = self.class.js_config.xtype
60
+
61
+ # Include our alias: Ext.createByAlias may be used to instantiate the component.
62
+ c.alias = self.class.js_config.class_alias
63
+
64
+ # So we can use getComponent(<component_name>) to retrieve a child component
65
+ c.item_id ||= name
66
+
67
+ c.i18n = js_translate_properties if js_translate_properties.present?
68
+
69
+ c.netzke_plugins = plugins.map{ |p| p.to_s.camelcase(:lower) } if plugins.present?
70
+
71
+ # we need to pass them as strigs, not as symbols
72
+ c.tools = c.tools.map(&:to_s) if c.tools.present?
73
+
74
+ c.flash = session[:flash] if session && session[:flash].present?
75
+ end
76
+
77
+ # Instance-level client class config. The result of this method (a hash) is converted to a JSON object and passed as options to the constructor of our JavaScript class.
78
+ # Not to be overridden, override {#js_configure} instead.
79
+ def js_config
80
+ @js_config ||= ActiveSupport::OrderedOptions.new.tap{|c| js_configure(c)}
81
+ end
82
+
83
+ # Hash containing configuration for all child components to be instantiated at the JS side
84
+ def js_components
85
+ @js_components ||= eagerly_loaded_components.inject({}) do |out, (name, config)|
86
+ instance = component_instance(name.to_sym)
87
+ out.merge(name => instance.js_config)
88
+ end
89
+ end
90
+
91
+ # All the JS-code required by this instance of the component to be instantiated in the browser.
92
+ # It includes JS-classes for the parents, eagerly loaded child components, and itself.
93
+ def js_missing_code(cached = [])
94
+ code = dependency_classes.inject("") do |r,k|
95
+ cached.include?(k.js_config.xtype) ? r : r + k.js_config.code_with_dependencies#.strip_js_comments
96
+ end
97
+ code.blank? ? nil : code
98
+ end
99
+
100
+ private
101
+
102
+ # Merges all the translations in the class hierarchy
103
+ # Note: this method can't be moved out to ClientClass, because I18n is loaded only once, when other Ruby classes are evaluated; so, this must remain at instance level.
104
+ def js_translate_properties
105
+ @js_translate_properties ||= self.class.netzke_ancestors.inject({}) do |r,klass|
106
+ hsh = klass.js_config.translated_properties.inject({}) { |h,t| h.merge(t => I18n.t("#{klass.i18n_id}.#{t}")) }
107
+ r.merge(hsh)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,11 @@
1
+ module Netzke
2
+ module Core
3
+ # A very simple panel with an automatically set title. Can be used as a child component +klass+.
4
+ class Panel < Netzke::Base
5
+ def configure(c)
6
+ c.title ||= name.to_s.humanize
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
- module Netzke
1
+ module Netzke::Core
2
2
  module Plugins
3
3
  extend ActiveSupport::Concern
4
4
 
@@ -10,20 +10,25 @@ module Netzke
10
10
 
11
11
  module ClassMethods
12
12
  # Defines a plugin
13
- def plugin(name, config = {}, &block)
14
- component(name, config, &block)
13
+ def plugin(name, &block)
15
14
  register_plugin(name)
15
+ component name do |c|
16
+ block.call(c) if block_given?
17
+
18
+ # plugins are *always* eagerly loaded
19
+ c.eager_loading = true
20
+ end
16
21
  end
17
22
 
23
+ private
18
24
  # Register a plugin
19
25
  def register_plugin(name)
20
26
  self.registered_plugins |= [name]
21
27
  end
22
-
23
28
  end
24
29
 
25
30
  def plugins
26
31
  self.class.registered_plugins
27
32
  end
28
33
  end
29
- end
34
+ end