netzke-core 0.8.1 → 0.8.2

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 (216) hide show
  1. data/CHANGELOG.md +16 -1
  2. data/Gemfile +12 -0
  3. data/README.md +22 -15
  4. data/Rakefile +19 -38
  5. data/app/controllers/netzke_controller.rb +1 -79
  6. data/javascripts/ext.js +17 -13
  7. data/lib/netzke/base.rb +6 -2
  8. data/lib/netzke/core/action_config.rb +7 -0
  9. data/lib/netzke/core/actions.rb +6 -32
  10. data/lib/netzke/core/client_class.rb +1 -1
  11. data/lib/netzke/core/component_config.rb +1 -1
  12. data/lib/netzke/core/composition.rb +17 -111
  13. data/lib/netzke/core/config_to_dsl_delegator.rb +0 -7
  14. data/lib/netzke/core/configuration.rb +48 -0
  15. data/lib/netzke/core/dsl_support.rb +71 -0
  16. data/lib/netzke/core/dynamic_assets.rb +10 -1
  17. data/lib/netzke/core/embedding.rb +2 -2
  18. data/lib/netzke/core/html.rb +29 -0
  19. data/lib/netzke/core/javascript.rb +32 -26
  20. data/lib/netzke/core/railz/action_view_ext/ext.rb +2 -2
  21. data/lib/netzke/core/railz/controller_extensions.rb +96 -3
  22. data/lib/netzke/core/railz/routes.rb +14 -3
  23. data/lib/netzke/core/ruby_ext/array.rb +4 -18
  24. data/lib/netzke/core/ruby_ext/hash.rb +19 -25
  25. data/lib/netzke/core/ruby_ext/time_with_zone.rb +1 -1
  26. data/lib/netzke/core/ruby_ext.rb +0 -2
  27. data/lib/netzke/core/session.rb +8 -1
  28. data/lib/netzke/core/state.rb +3 -3
  29. data/lib/netzke/core/version.rb +1 -1
  30. data/lib/netzke/core.rb +15 -7
  31. data/lib/netzke-core.rb +2 -9
  32. data/tasks/app_test_tasks.rake +94 -0
  33. data/tasks/rake_helper.rb +51 -0
  34. data/test/core_test_app/README +2 -2
  35. data/test/core_test_app/app/assets/javascripts/expect/expect.js +1253 -0
  36. data/test/core_test_app/app/assets/javascripts/mocha/mocha.js +5340 -0
  37. data/test/core_test_app/app/assets/stylesheets/mocha/mocha.css +231 -0
  38. data/test/core_test_app/app/components/{component_with_actions.rb → actions.rb} +7 -9
  39. data/test/core_test_app/app/components/{some_composite.rb → composition.rb} +16 -5
  40. data/test/core_test_app/app/components/{component_with_custom_css → css_inclusion}/stylesheets/custom.css +2 -2
  41. data/test/core_test_app/app/components/css_inclusion.rb +12 -0
  42. data/test/core_test_app/app/components/{component_loader/javascripts/component_loader.js → dynamic_loading/javascripts/dynamic_loading.js} +9 -1
  43. data/test/core_test_app/app/components/{component_loader.rb → dynamic_loading.rb} +12 -5
  44. data/test/core_test_app/app/components/{server_caller/javascripts/server_caller.js → endpoints/javascripts/endpoints.js} +10 -6
  45. data/test/core_test_app/app/components/{server_caller.rb → endpoints.rb} +12 -8
  46. data/test/core_test_app/app/components/{extended_server_caller.rb → endpoints_extended.rb} +6 -4
  47. data/test/core_test_app/app/components/ext_direct/composite.rb +5 -1
  48. data/test/core_test_app/app/components/feedback.rb +26 -0
  49. data/test/core_test_app/app/components/haml_panel/html/body.html.haml +10 -0
  50. data/test/core_test_app/app/components/haml_panel/html/server_response.html.haml +3 -0
  51. data/test/core_test_app/app/components/haml_panel.rb +32 -0
  52. data/test/core_test_app/app/components/hello_world.rb +1 -0
  53. data/test/core_test_app/app/components/js_inclusion/javascripts/extra_one.js +2 -0
  54. data/test/core_test_app/app/components/js_inclusion/javascripts/extra_two.js +2 -0
  55. data/test/core_test_app/app/components/js_inclusion/javascripts/js_inclusion.js +5 -0
  56. data/test/core_test_app/app/components/{component_with_js_mixin → js_inclusion}/javascripts/method_set_one.js +0 -0
  57. data/test/core_test_app/app/components/{component_with_js_mixin → js_inclusion}/javascripts/method_set_two.js +0 -0
  58. data/test/core_test_app/app/components/{component_with_js_mixin.rb → js_inclusion.rb} +3 -3
  59. data/test/core_test_app/app/components/js_inclusion_extended/javascripts/some_method_set.js +5 -0
  60. data/test/core_test_app/app/components/js_inclusion_extended.rb +6 -0
  61. data/test/core_test_app/app/components/loaded_css_inclusion.rb +22 -0
  62. data/test/core_test_app/app/components/{localized_panel.rb → localization.rb} +5 -5
  63. data/test/core_test_app/app/components/localization_extended.rb +2 -0
  64. data/test/core_test_app/app/components/persistence.rb +60 -0
  65. data/test/core_test_app/app/components/persistence_with_shared_state.rb +7 -0
  66. data/test/core_test_app/app/components/plugin_with_actions.rb +24 -0
  67. data/test/core_test_app/app/components/plugin_with_components.rb +3 -3
  68. data/test/core_test_app/app/components/plugin_with_endpoints.rb +29 -0
  69. data/test/core_test_app/app/components/plugins.rb +9 -0
  70. data/test/core_test_app/app/components/{kinda_complex_component → ruby_modules}/basic_stuff.rb +1 -1
  71. data/test/core_test_app/app/components/{kinda_complex_component → ruby_modules}/extra_stuff.rb +3 -3
  72. data/test/core_test_app/app/components/{kinda_complex_component.rb → ruby_modules.rb} +1 -1
  73. data/test/core_test_app/app/components/scoped/deeply_scoped/scoping.rb +10 -0
  74. data/test/core_test_app/app/components/scoped/scoping.rb +8 -0
  75. data/test/core_test_app/app/components/scoped/scoping_extended.rb +8 -0
  76. data/test/core_test_app/app/components/self_reloading.rb +25 -0
  77. data/test/core_test_app/app/components/server_counter/javascripts/server_counter.js +4 -4
  78. data/test/core_test_app/app/components/server_counter.rb +10 -10
  79. data/test/core_test_app/app/components/simple_authentication_component.rb +1 -0
  80. data/test/core_test_app/app/components/simple_component.rb +0 -4
  81. data/test/core_test_app/app/components/simple_composite.rb +1 -1
  82. data/test/core_test_app/app/components/simple_form_with_file_upload.rb +1 -2
  83. data/test/core_test_app/app/components/simple_tab_panel.rb +5 -3
  84. data/test/core_test_app/app/components/{panel_with_tools.rb → tools.rb} +3 -3
  85. data/test/core_test_app/app/components/window_with_simple_component.rb +1 -0
  86. data/test/core_test_app/app/controllers/alternative_controller.rb +10 -0
  87. data/test/core_test_app/app/controllers/specs_controller.rb +11 -0
  88. data/test/core_test_app/app/views/layouts/application.html.erb +19 -1
  89. data/test/core_test_app/app/views/simple_rails/multiple_nested.html.erb +2 -2
  90. data/test/core_test_app/config/boot.rb +3 -10
  91. data/test/core_test_app/config/environments/development.rb +1 -0
  92. data/test/core_test_app/config/initializers/netzke.rb +4 -1
  93. data/test/core_test_app/config/locales/en.yml +11 -4
  94. data/test/core_test_app/config/locales/es.yml +1 -4
  95. data/test/core_test_app/config/routes.rb +10 -1
  96. data/test/core_test_app/core_test_app.tmproj +254 -0
  97. data/test/core_test_app/db/development.sqlite3 +0 -0
  98. data/test/core_test_app/{lib/tasks/.gitkeep → db/test.sqlite3} +0 -0
  99. data/test/core_test_app/log/development.log +78046 -0
  100. data/test/core_test_app/log/production.log +18 -0
  101. data/test/core_test_app/log/test.log +120048 -0
  102. data/test/core_test_app/rails_app.tmproj +324 -0
  103. data/test/core_test_app/tmp/cache/assets/C8B/BF0/sprockets%2F54de2792b036d1dab855f88599503551 +0 -0
  104. data/test/core_test_app/tmp/cache/assets/C92/5A0/sprockets%2F39e75754782ee12179bf35c9a0971d80 +0 -0
  105. data/test/core_test_app/tmp/cache/assets/C99/720/sprockets%2F981d5a1b957a012e380b22011a6d176d +0 -0
  106. data/test/core_test_app/tmp/cache/assets/C9F/750/sprockets%2F20ce3d64040a5d3a0a8883bd60754356 +0 -0
  107. data/test/core_test_app/tmp/cache/assets/CC4/C00/sprockets%2Fc615df52887d8c2e67e8413576a419c5 +0 -0
  108. data/test/core_test_app/tmp/cache/assets/CF1/3F0/sprockets%2Fc69ee42924fab565a3533d56473ce878 +0 -0
  109. data/test/core_test_app/tmp/cache/assets/D0E/870/sprockets%2Fa593bf4fac106add88c9434141a49663 +0 -0
  110. data/test/core_test_app/tmp/cache/assets/D14/8E0/sprockets%2F20748e8d1d7d090d122904a9fe6f18fc +0 -0
  111. data/test/core_test_app/tmp/cache/assets/D3E/DA0/sprockets%2Fa175f1ac5996544b908ba3ba3f64c4f3 +0 -0
  112. data/test/core_test_app/tmp/cache/assets/D43/C00/sprockets%2F7bc60c758776356d615ab5edff201ee2 +0 -0
  113. data/test/core_test_app/tmp/cache/assets/D4B/C50/sprockets%2F8483b7e322da338e8f9eb3b30a957e9a +0 -0
  114. data/test/core_test_app/tmp/cache/assets/D64/090/sprockets%2F5a01ff309c3f2503eb5e4f5667cca4b3 +0 -0
  115. data/test/core_test_app/tmp/cache/assets/D8B/FB0/sprockets%2F7a86225caaa389f1be600b4f3a2d1ef0 +0 -0
  116. data/test/core_test_app/tmp/cache/assets/D98/9C0/sprockets%2F18b80e8fe200aebc522e561a867ea6fb +0 -0
  117. data/test/core_test_app/tmp/cache/assets/DB0/6E0/sprockets%2F03e33f5a4779eeb48bcfc86ee717fb55 +0 -0
  118. data/test/core_test_app/tmp/cache/assets/DED/7E0/sprockets%2Feaedd52ba538f19e4ab543a3e20ce2c4 +0 -0
  119. data/test/core_test_app/tmp/cache/assets/E07/FF0/sprockets%2Fb3c071e0a6de36f041adbbdaa8ab060b +0 -0
  120. data/test/core_test_app/tmp/capybara/capybara-20101214105940.html +40 -0
  121. data/test/core_test_app/tmp/capybara/capybara-20101214110642.html +40 -0
  122. data/test/core_test_app/tmp/capybara/capybara-20101214110749.html +40 -0
  123. data/test/core_test_app/tmp/capybara/capybara-20101214110750.html +40 -0
  124. data/test/core_test_app/tmp/capybara/capybara-20101214111025.html +40 -0
  125. data/test/core_test_app/tmp/capybara/capybara-20101214111027.html +40 -0
  126. data/test/core_test_app/tmp/capybara/capybara-20101214111213.html +40 -0
  127. data/test/core_test_app/tmp/capybara/capybara-20101214111214.html +40 -0
  128. data/test/core_test_app/tmp/capybara/capybara-20101214111332.html +40 -0
  129. data/test/core_test_app/tmp/capybara/capybara-20101214111333.html +40 -0
  130. data/test/core_test_app/{spec/component → tmp/pids/passenger.3000.pid.lock} +0 -0
  131. metadata +370 -133
  132. data/.autotest +0 -1
  133. data/.travis.yml +0 -18
  134. data/Manifest +0 -50
  135. data/config/ci/before-travis.sh +0 -10
  136. data/install.rb +0 -1
  137. data/lib/netzke/core/options_hash.rb +0 -27
  138. data/lib/netzke/core/ruby_ext/string.rb +0 -26
  139. data/lib/netzke/core/ruby_ext/symbol.rb +0 -13
  140. data/netzke-core.gemspec +0 -253
  141. data/test/core_test_app/.gitignore +0 -4
  142. data/test/core_test_app/.powrc +0 -4
  143. data/test/core_test_app/.rvmrc +0 -1
  144. data/test/core_test_app/Gemfile +0 -19
  145. data/test/core_test_app/Gemfile.lock +0 -147
  146. data/test/core_test_app/app/components/border_layout_panel.rb +0 -4
  147. data/test/core_test_app/app/components/card_component_loader.rb +0 -25
  148. data/test/core_test_app/app/components/component_with_custom_css.rb +0 -11
  149. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/component_with_js_mixin.js +0 -5
  150. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_one.js +0 -2
  151. data/test/core_test_app/app/components/component_with_js_mixin/javascripts/extra_two.js +0 -2
  152. data/test/core_test_app/app/components/component_with_nested_through.rb +0 -28
  153. data/test/core_test_app/app/components/component_with_required_js.rb +0 -24
  154. data/test/core_test_app/app/components/dsl_delegated_properties.rb +0 -4
  155. data/test/core_test_app/app/components/dsl_delegated_properties_base.rb +0 -5
  156. data/test/core_test_app/app/components/extended_component_with_actions.rb +0 -9
  157. data/test/core_test_app/app/components/extended_component_with_js_mixin/javascripts/some_method_set.js +0 -5
  158. data/test/core_test_app/app/components/extended_component_with_js_mixin.rb +0 -10
  159. data/test/core_test_app/app/components/extended_localized_panel.rb +0 -2
  160. data/test/core_test_app/app/components/included.js +0 -5
  161. data/test/core_test_app/app/components/inline_composite.rb +0 -13
  162. data/test/core_test_app/app/components/loader_of_component_with_custom_css.rb +0 -23
  163. data/test/core_test_app/app/components/multipane_component_loader.rb +0 -41
  164. data/test/core_test_app/app/components/nested_component.rb +0 -17
  165. data/test/core_test_app/app/components/panel_with_plugin.rb +0 -9
  166. data/test/core_test_app/app/components/scoped_components/deep_scoped_components/some_deep_scoped_component.rb +0 -10
  167. data/test/core_test_app/app/components/scoped_components/extended_scoped_component.rb +0 -8
  168. data/test/core_test_app/app/components/scoped_components/some_scoped_component.rb +0 -8
  169. data/test/core_test_app/app/components/some_ext_component.rb +0 -8
  170. data/test/core_test_app/app/components/some_plugin.rb +0 -40
  171. data/test/core_test_app/app/components/stateful_component.rb +0 -46
  172. data/test/core_test_app/app/components/stateful_component_with_shared_state.rb +0 -11
  173. data/test/core_test_app/config/database.yml.travis +0 -11
  174. data/test/core_test_app/db/schema.rb +0 -29
  175. data/test/core_test_app/features/actions_and_tools.feature +0 -22
  176. data/test/core_test_app/features/basic.feature +0 -7
  177. data/test/core_test_app/features/client-server.feature +0 -19
  178. data/test/core_test_app/features/complex_component.feature +0 -18
  179. data/test/core_test_app/features/component.feature +0 -10
  180. data/test/core_test_app/features/component_loader.feature +0 -52
  181. data/test/core_test_app/features/composition.feature +0 -45
  182. data/test/core_test_app/features/config_to_dsl_delegation.feature +0 -10
  183. data/test/core_test_app/features/custom_css.feature +0 -17
  184. data/test/core_test_app/features/ext.direct.feature +0 -32
  185. data/test/core_test_app/features/file_inclusion.feature +0 -10
  186. data/test/core_test_app/features/i18n.feature +0 -35
  187. data/test/core_test_app/features/inheritance.feature +0 -18
  188. data/test/core_test_app/features/js_include.feature +0 -20
  189. data/test/core_test_app/features/nested_views.feature +0 -10
  190. data/test/core_test_app/features/persistence.feature +0 -34
  191. data/test/core_test_app/features/plugin.feature +0 -16
  192. data/test/core_test_app/features/rails_views.feature +0 -16
  193. data/test/core_test_app/features/scopes.feature +0 -14
  194. data/test/core_test_app/features/step_definitions/custom_css_steps.rb +0 -7
  195. data/test/core_test_app/features/step_definitions/generic_steps.rb +0 -64
  196. data/test/core_test_app/features/step_definitions/web_steps.rb +0 -219
  197. data/test/core_test_app/features/support/env.rb +0 -58
  198. data/test/core_test_app/features/support/paths.rb +0 -42
  199. data/test/core_test_app/spec/action_config_spec.rb +0 -15
  200. data/test/core_test_app/spec/actions_spec.rb +0 -96
  201. data/test/core_test_app/spec/base_spec.rb +0 -35
  202. data/test/core_test_app/spec/client_class_spec.rb +0 -17
  203. data/test/core_test_app/spec/composition_spec.rb +0 -118
  204. data/test/core_test_app/spec/core_ext_spec.rb +0 -27
  205. data/test/core_test_app/spec/endpoint_response_spec.rb +0 -17
  206. data/test/core_test_app/spec/javascript_spec.rb +0 -33
  207. data/test/core_test_app/spec/js_class_config_scope.rb +0 -37
  208. data/test/core_test_app/spec/panel_spec.rb +0 -11
  209. data/test/core_test_app/spec/services_spec.rb +0 -16
  210. data/test/core_test_app/spec/spec.opt +0 -2
  211. data/test/core_test_app/spec/spec_helper.rb +0 -27
  212. data/test/core_test_app/spec/state_spec.rb +0 -20
  213. data/test/core_test_app/vendor/plugins/.gitkeep +0 -0
  214. data/test/unit/core_ext_test.rb +0 -8
  215. data/test/unit/netzke_core_test.rb +0 -178
  216. data/uninstall.rb +0 -1
data/CHANGELOG.md CHANGED
@@ -1,6 +1,21 @@
1
+ # v0.8.2 - 2013-03-12
2
+ * bug fix
3
+ * RuntimeError "can't add a new key into hash during iteration" in Composition in some scenarious (thanks @wupdiwup)
4
+ * netzkeReload works again
5
+
6
+ * improvements
7
+ * minimize core Ruby class extensions
8
+ * tests can now be run by simply executing `rake` from the gem's root (thanks @allomov)
9
+ * feedback delay is now globally configurable
10
+ * netzkeFeedback now understands {delay: seconds} as second parameter
11
+ * add support for arbitrary controllers replacing NetzkeController
12
+ * add support for HAML templates
13
+ * some code refactoring
14
+ * tests are rewritten with Mocha.js and CoffeeScript
15
+
1
16
  # v0.8.1 - 2012-12-15
2
17
  * bug fix
3
- * in production, JS comment stripping could cause modification of form_authenticity_token (issue #43) - by @scho
18
+ * in production, JS comment stripping could cause modification of form_authenticity_token (issue #43) (thanks @scho)
4
19
 
5
20
  # v0.8.0 - 2012-12-09
6
21
  ## Misc
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'haml'
6
+
7
+ group :test do
8
+ gem 'capybara'
9
+ gem 'database_cleaner'
10
+ gem 'rspec-rails'
11
+ gem 'pry-rails'
12
+ end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Netzke Core [![Build Status](https://secure.travis-ci.org/nomadcoder/netzke-core.png?branch=master)](http://travis-ci.org/nomadcoder/netzke-core) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/netzke/netzke-core)
1
+ # Netzke Core [![Gem Version](https://fury-badge.herokuapp.com/rb/netzke-core.png)](http://badge.fury.io/rb/netzke-core) [![Build Status](https://travis-ci.org/netzke/netzke-core.png?branch=master)](https://travis-ci.org/netzke/netzke-core) [![Code Climate](https://codeclimate.com/github/netzke/netzke-core.png)](https://codeclimate.com/github/netzke/netzke-core)
2
2
 
3
3
  [RDocs](http://rdoc.info/projects/netzke/netzke-core)
4
4
 
@@ -31,6 +31,8 @@ All this extremely facilitates building fast, low-traffic, robust, and highly ma
31
31
 
32
32
  *This component is distributed as a part of the test application, see `test/core_test_app/components`.*
33
33
 
34
+ Ext JS files are not distributed with Netzke, so, make sure that they are located in (or sym-linked as) `YOUR_APP/public/extjs`.
35
+
34
36
  In `YOUR_APP/components/hello_world.rb`:
35
37
 
36
38
  ```ruby
@@ -248,7 +250,7 @@ Actions can also be referred to is submenus:
248
250
  c.tbar = [{text: 'Menu', menu: {items: [:show_report]}}]
249
251
  ```
250
252
 
251
- For more details on composition refer to [Netzke::Core::Action](http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Action).
253
+ For more details on composition refer to [Netzke::Core::Actions](http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Actions).
252
254
 
253
255
  ## Client-server interaction
254
256
 
@@ -285,7 +287,7 @@ An endpoint can instruct the client class to execute a set of methods after its
285
287
  ```ruby
286
288
  class SimpleComponent < Netzke::Base
287
289
  endpoint :whats_up_server do |params, this|
288
- this.set_title("All quiet here on the server")
290
+ this.set_title("Response from server")
289
291
  this.my_method
290
292
  end
291
293
  end
@@ -317,6 +319,10 @@ Netzke Core will automatically include Ext JS localization files based on curren
317
319
 
318
320
  Also, Netzke Core uses some conventions for localizing actions. Refer to [Netzke::Core::Actions](http://rdoc.info/github/netzke/netzke-core/Netzke/Core/Actions).
319
321
 
322
+ ## HAML support (experimental)
323
+
324
+ Netzke provides support for HAML templates in case you don't want to put HTML into Ruby files.
325
+
320
326
  ## Requirements
321
327
 
322
328
  * Ruby ~> 1.9.2
@@ -325,41 +331,42 @@ Also, Netzke Core uses some conventions for localizing actions. Refer to [Netzke
325
331
 
326
332
  ## Installation
327
333
 
328
- $ gem install netzke-core
334
+ $ gem install netzke-core
329
335
 
330
336
  For the latest ("edge") stuff, instruct the bundler to get the gem straight from github:
331
337
 
332
338
  ```ruby
333
- gem 'netzke-core', git: "git://github.com/netzke/netzke-core.git"
339
+ gem 'netzke-core', github: "netzke/netzke-core"
334
340
  ```
335
341
 
336
- By default, Netzke assumes that your Ext JS library is located in public/extjs. It can be a symbolic link, e.g.:
342
+ By default, Netzke assumes that your Ext JS library is located in `public/extjs`. It can be a symbolic link, e.g.:
337
343
 
338
- $ ln -s ~/code/sencha/ext-4.1.1 public/extjs
344
+ $ ln -s PATH/TO/YOUR/EXTJS/FILES public/extjs
339
345
 
340
346
  *(Make sure that the location of the license.txt distributed with Ext JS is exactly `public/extjs/license.txt`)*
341
347
 
342
348
  ## Running tests
343
349
 
344
- The bundled `test/core_test_app` application used for automated testing can be easily run as a stand-alone Rails app. It's a good source of concise, focused examples. After starting the application, access any of the test components (located in `app/components`) by using the following url:
350
+ The bundled `test/core_test_app` application used for automated testing can be easily run as a stand-alone Rails app. It's a good source of concise, focused examples. After starting the application, access any of the test components (located in `test/core_test_app/app/components`) by using the following url:
345
351
 
346
352
  http://localhost:3000/components/{name of the component's class}
347
353
 
348
- For example [http://localhost:3000/components/ServerCaller](http://localhost:3000/components/ServerCaller)
354
+ For example [http://localhost:3000/components/Endpoints](http://localhost:3000/components/Endpoints)
349
355
 
350
- Before being able run the test app and the tests themselves, you must link your Ext JS library to `test/core_test_app/public`, e.g. (from the gems's root):
356
+ To run a specific Mocha JS spec (located in `spec/mocha`) for a component, append `?spec={name of spec}`, for example:
351
357
 
352
- $ ln -s ~/code/sencha/ext-4.1.1 test/core_test_app/public/extjs
358
+ [http://localhost:3000/components/Endpoints?spec=endpoints](http://localhost:3000/components/Endpoints?spec=endpoints)
353
359
 
354
- For cucumber tests (from `test/core_test_app`):
360
+ To run all the tests (from the gem's root):
355
361
 
356
- $ cucumber features
362
+ $ rake
357
363
 
358
- For RSpec tests (from `test/core_test_app`):
364
+ This assumes that the Ext JS library is located/symlinked in `test/core_test_app/public/extjs`. If you want to use Sencha CDN instead, run:
359
365
 
360
- $ rspec spec
366
+ $ EXTJS_SRC=cdn rake
361
367
 
362
368
  ## Useful links
369
+
363
370
  * [Project website](http://netzke.org)
364
371
  * [Live demo](http://netzke-demo.herokuapp.com) (features [Netzke Basepack](https://github.com/netzke/netzke-basepack), with sample code)
365
372
  * [Twitter](http://twitter.com/netzke) - latest news about the framework
data/Rakefile CHANGED
@@ -1,44 +1,25 @@
1
- begin
2
- require 'jeweler'
3
- require './lib/netzke/core/version'
4
- Jeweler::Tasks.new do |gemspec|
5
- gemspec.version = Netzke::Core::Version::STRING
6
- gemspec.name = "netzke-core"
7
- gemspec.summary = "Client-server GUI components with Sencha Ext JS and Ruby"
8
- gemspec.description = "Allows building complex RIA by greatly facilitating modular development"
9
- gemspec.email = "nmcoder@gmail.com"
10
- gemspec.homepage = "http://netzke.org"
11
- gemspec.authors = ["nomadcoder"]
12
- gemspec.add_dependency("activesupport", ">=3.1.0")
13
- end
14
- Jeweler::GemcutterTasks.new
15
- rescue LoadError
16
- puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
- end
1
+ require "bundler/gem_tasks"
2
+ require 'yard'
18
3
 
19
- require 'rake/testtask'
20
- Rake::TestTask.new(:test) do |test|
21
- test.libs << 'lib' << 'test'
22
- test.pattern = 'test/**/*_test.rb'
23
- test.verbose = true
24
- end
4
+ # Load tasks, that will be available for Rails user
5
+ Dir[File.join(File.dirname(__FILE__), './lib/tasks/*.rake')].each { |file| load file }
25
6
 
26
- begin
27
- require 'yard'
7
+ # Load tasks for gem development
8
+ Dir[File.join(File.dirname(__FILE__), 'tasks/*.rake')].each { |file| load file }
28
9
 
29
- YARD::Rake::YardocTask.new do |t|
30
- t.options = ['--title', "Netzke Core #{Netzke::Core::Version::STRING}"]
31
- end
10
+ YARD::Rake::YardocTask.new do |t|
11
+ t.options = ['--title', "Netzke Core #{Netzke::Core::Version::STRING}"]
12
+ end
32
13
 
33
- namespace :yard do
34
- desc "Publish docs to api.netzke.org"
35
- task publish: :yard do
36
- dir = 'www/api.netzke.org/core'
37
- puts "Publishing to fl:#{dir}..."
38
- `ssh fl "mkdir -p #{dir}"`
39
- `scp -r doc/* fl:#{dir}`
40
- end
14
+ namespace :yard do
15
+ desc "Publish docs to api.netzke.org"
16
+ task publish: :yard do
17
+ dir = 'www/api.netzke.org/core'
18
+ puts "Publishing to fl:#{dir}..."
19
+ `ssh fl "mkdir -p #{dir}"`
20
+ `scp -r doc/* fl:#{dir}`
41
21
  end
42
- rescue
43
- puts "To enable yard do 'gem install yard'"
44
22
  end
23
+
24
+ desc 'rake test'
25
+ task default: :test
@@ -1,81 +1,3 @@
1
1
  class NetzkeController < ApplicationController
2
- # Action for Ext.Direct RPC calls
3
- def direct
4
- result=""
5
- error=false
6
- if params['_json'] # this is a batched request
7
- params['_json'].each do |batch|
8
- result += result.blank? ? '[' : ', '
9
- begin
10
- result += invoke_endpoint(batch[:act], batch[:method].underscore, batch[:data].first, batch[:tid])
11
- rescue Exception => e
12
- logger.error "!!! Netzke: Error invoking endpoint: #{batch[:act]} #{batch[:method].underscore} #{batch[:data].inspect} #{batch[:tid]}\n"
13
- logger.error e.message
14
- logger.error e.backtrace.join("\n")
15
- error=true
16
- break;
17
- end
18
- end
19
- result+=']'
20
- else # this is a single request
21
- result=invoke_endpoint params[:act], params[:method].underscore, params[:data].first, params[:tid]
22
- end
23
- render :text => result, :layout => false, :status => error ? 500 : 200
24
- end
25
-
26
- # On-the-fly generation of public/netzke/ext.[js|css]
27
- def ext
28
- respond_to do |format|
29
- format.js {
30
- render :text => Netzke::Core::DynamicAssets.ext_js(form_authenticity_token)
31
- }
32
-
33
- format.css {
34
- render :text => Netzke::Core::DynamicAssets.ext_css
35
- }
36
- end
37
- end
38
-
39
- # Old-way action used at multi-part form submission (endpointUrl)
40
- def dispatcher
41
- endpoint_dispatch(params[:address])
42
- end
43
-
44
- protected
45
-
46
- def invoke_endpoint(endpoint_path, action, params, tid)
47
- component_name, *sub_components = endpoint_path.split('__')
48
- components_in_session = session[:netzke_components]
49
-
50
- if components_in_session
51
- component_instance = Netzke::Base.instance_by_config(components_in_session[component_name.to_sym])
52
- result = component_instance.invoke_endpoint((sub_components + [action]).join("__"), params).to_nifty_json
53
- else
54
- result = {:netzke_component_not_in_session => true}.to_nifty_json
55
- end
56
-
57
- # We render text/plain, so that the browser never modifies our response
58
- response.headers["Content-Type"] = "text/plain; charset=utf-8"
59
-
60
- { :type => "rpc",
61
- :tid => tid,
62
- :action => component_name,
63
- :method => action,
64
- :result => result.present? && result.l || {}
65
- }.to_json
66
- end
67
-
68
- # The dispatcher for the old-style requests (used for multi-part form submission). The URL contains the name of the component,
69
- # as well as the method of this component to be called, according to the double underscore notation.
70
- # E.g.: some_grid__post_grid_data.
71
- def endpoint_dispatch(endpoint_path)
72
- component_name, *sub_components = endpoint_path.split('__')
73
- component_instance = Netzke::Base.instance_by_config(session[:netzke_components][component_name.to_sym])
74
-
75
- # We can't do this here; this method is only used for classic form submission, and the response from the server should be the (default) "text/html"
76
- # response.headers["Content-Type"] = "text/plain; charset=utf-8"
77
-
78
- render :text => component_instance.invoke_endpoint(sub_components.join("__"), params).to_nifty_json, :layout => false
79
- end
80
-
2
+ include Netzke::Railz::ControllerExtensions
81
3
  end
data/javascripts/ext.js CHANGED
@@ -22,25 +22,26 @@ Ext.QuickTips.init();
22
22
 
23
23
  // FeedbackGhost is a little class that displays unified feedback from Netzke components.
24
24
  Ext.define('Netzke.FeedbackGhost', {
25
- showFeedback: function(msg){
26
- if (!msg) Netzke.exception("Netzke.FeedbackGhost#showFeedback: wrong number of arguments (0 for 1)");
25
+ showFeedback: function(msg, options){
26
+ options = options || {};
27
+ options.delay = options.delay || Netzke.core.FeedbackDelay;
27
28
  if (Ext.isObject(msg)) {
28
- this.msg(msg.level.camelize(), msg.msg);
29
+ this.msg(msg.level.camelize(), msg.msg, options.delay);
29
30
  } else if (Ext.isArray(msg)) {
30
31
  Ext.each(msg, function(m) { this.showFeedback(m); }, this);
31
32
  } else {
32
- this.msg(null, msg); // no header for now
33
+ this.msg(null, msg, options.delay); // no header for now
33
34
  }
34
35
  },
35
36
 
36
- msg: function(title, format){
37
+ msg: function(title, format, delay){
37
38
  if(!this.msgCt){
38
39
  this.msgCt = Ext.core.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
39
40
  }
40
41
  var s = Ext.String.format.apply(String, Array.prototype.slice.call(arguments, 1));
41
42
  var m = Ext.core.DomHelper.append(this.msgCt, this.createBox(title, s), true);
42
43
  m.hide();
43
- m.slideIn('t').ghost("t", { delay: 1000, remove: true});
44
+ m.slideIn('t').ghost("t", { delay: delay, remove: true});
44
45
  },
45
46
 
46
47
  createBox: function(t, s){
@@ -356,12 +357,15 @@ Ext.define(null, {
356
357
  },
357
358
 
358
359
  /**
359
- * Reloads current component (calls the parent to reload us as its component)
360
+ * Reloads itself by instructing the parent to call `netzkeLoadComponent`.
361
+ * Note: in order for this to work, the component must be nested in a container with the 'fit' layout.
360
362
  */
361
363
  netzkeReload: function(){
362
364
  var parent = this.netzkeGetParentComponent();
365
+
363
366
  if (parent) {
364
- parent.netzkeLoadComponent({id:this.netzkeLocalId(parent), container:this.ownerCt.id});
367
+ var name = this.netzkeLocalId(parent);
368
+ parent.netzkeLoadComponent(name, {container:this.ownerCt.id});
365
369
  } else {
366
370
  window.location.reload();
367
371
  }
@@ -396,13 +400,13 @@ Ext.define(null, {
396
400
  /**
397
401
  * Provides a visual feedback. TODO: refactor
398
402
  */
399
- netzkeFeedback: function(msg){
400
- if (this.initialConfig && this.initialConfig.quiet) {
401
- return false;
402
- }
403
+ netzkeFeedback: function(msg, options){
404
+ if (this.initialConfig && this.initialConfig.quiet) return false;
405
+
406
+ options = options || {};
403
407
 
404
408
  if (this.feedbackGhost) {
405
- this.feedbackGhost.showFeedback(msg);
409
+ this.feedbackGhost.showFeedback(msg, {delay: options.delay});
406
410
  } else {
407
411
  // there's no application to show the feedback - so, we do it ourselves
408
412
  if (typeof msg == 'string'){
data/lib/netzke/base.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'active_support/core_ext'
2
2
  require 'netzke/core/ruby_ext'
3
+ require 'netzke/core/dsl_support'
3
4
  require 'netzke/core/javascript'
4
5
  require 'netzke/core/stylesheets'
5
6
  require 'netzke/core/services'
@@ -10,6 +11,7 @@ require 'netzke/core/state'
10
11
  require 'netzke/core/embedding'
11
12
  require 'netzke/core/actions'
12
13
  require 'netzke/core/session'
14
+ require 'netzke/core/html' if Module.const_defined?(:Haml)
13
15
 
14
16
  module Netzke
15
17
  # The base class for every Netzke component. Its main responsibilities include:
@@ -43,6 +45,7 @@ module Netzke
43
45
  #
44
46
  # This doesn't necessarily have to be used in toolbars, but also in other places in config (i.e. layouts).
45
47
  class Base
48
+ include Core::DslSupport
46
49
  include Core::Session
47
50
  include Core::State
48
51
  include Core::Configuration
@@ -53,7 +56,9 @@ module Netzke
53
56
  include Core::Stylesheets
54
57
  include Core::Embedding
55
58
  include Core::Actions
59
+ include Core::Html if const_defined? :Haml
56
60
 
61
+ # DELETE ME
57
62
  class_attribute :default_instance_config
58
63
  self.default_instance_config = {}
59
64
 
@@ -104,8 +109,7 @@ module Netzke
104
109
 
105
110
  # Instantiates a component instance. A parent can optionally be provided.
106
111
  def initialize(conf = {}, parent = nil)
107
- @passed_config = conf # configuration passed at the moment of instantiation
108
- @passed_config.deep_freeze
112
+ @passed_config = conf.deep_dup # configuration passed at the moment of instantiation
109
113
  @parent = parent
110
114
  @name = conf[:name] || self.class.name.underscore
111
115
  @js_id = parent.nil? ? @name : "#{parent.js_id}__#{@name}"
@@ -4,6 +4,8 @@ module Netzke::Core
4
4
  # class MyComponent < Netzke::Base
5
5
  # action :do_something do |c|
6
6
  # c.text = "Do it!"
7
+ # c.tooltip = "Do something"
8
+ # c.icon = :tick
7
9
  # end
8
10
  # end
9
11
  class ActionConfig < ActiveSupport::OrderedOptions
@@ -14,6 +16,7 @@ module Netzke::Core
14
16
 
15
17
  build_localized_attributes
16
18
 
19
+ self.name = @name
17
20
  self.text = @text.presence || @name.humanize
18
21
  self.tooltip = @tooltip.presence || @name.humanize
19
22
  self.icon = @icon.to_sym if @icon.present?
@@ -23,6 +26,10 @@ module Netzke::Core
23
26
  self[:icon] = path.is_a?(Symbol) ? Netzke::Base.uri_to_icon(path) : path
24
27
  end
25
28
 
29
+ # later
30
+ def set_defaults!
31
+ end
32
+
26
33
  private
27
34
 
28
35
  def build_localized_attributes
@@ -67,29 +67,12 @@ module Netzke::Core
67
67
  module Actions
68
68
  extend ActiveSupport::Concern
69
69
 
70
- ACTION_METHOD_NAME = "%s_action"
71
-
72
70
  included do
73
- # Returns registered actions
74
- class_attribute :registered_actions
75
- self.registered_actions = []
71
+ # Declares Base.action, for declaring actions, and Base#actions, which returns a [Hash] of all action configs by name
72
+ declare_dsl_for :actions
76
73
  end
77
74
 
78
75
  module ClassMethods
79
- def action(name, &block)
80
- self.registered_actions |= [name]
81
-
82
- method_name = ACTION_METHOD_NAME % name
83
-
84
- if block_given?
85
- define_method(method_name, &block)
86
- else
87
- define_method(method_name) do |action_config|
88
- action_config
89
- end
90
- end
91
- end
92
-
93
76
  # Must stay public, used from ActionConfig
94
77
  # @return [String|nil] full URI to an icon file by its name (provided we have a controller)
95
78
  def uri_to_icon(icon)
@@ -97,24 +80,15 @@ module Netzke::Core
97
80
  end
98
81
  end
99
82
 
100
- # All actions for this instance
101
- def actions
102
- @actions ||= self.class.registered_actions.inject({}) do |res, name|
103
- action_config = Netzke::Core::ActionConfig.new(name, self)
104
- send(ACTION_METHOD_NAME % name, action_config)
105
- if action_config.excluded
106
- res.merge(name.to_sym => {excluded: true})
107
- else
108
- res.merge(name.to_sym => action_config)
109
- end
110
- end
111
- end
112
-
113
83
  def js_configure(c)
114
84
  super
115
85
  c.actions = actions
116
86
  end
117
87
 
88
+ def extend_item(item)
89
+ super detect_and_normalize(:action, item)
90
+ end
91
+
118
92
  private
119
93
  def uri_to_icon(icon)
120
94
  self.class.uri_to_icon(icon)
@@ -235,7 +235,7 @@ Netzke.cache.push('#{xtype}');
235
235
  end
236
236
 
237
237
  def properties_as_string
238
- [properties.to_nifty_json.chop, mixins_as_string].compact.join(",\n") + "}"
238
+ [properties.netzke_jsonify.to_json.chop, mixins_as_string].compact.join(",\n") + "}"
239
239
  end
240
240
 
241
241
  # Default extended class
@@ -1,6 +1,6 @@
1
1
  module Netzke::Core
2
2
  class ComponentConfig < ActiveSupport::OrderedOptions
3
- def initialize(name)
3
+ def initialize(name, parent)
4
4
  self.name = name.to_s
5
5
  end
6
6
 
@@ -79,16 +79,10 @@ module Netzke::Core
79
79
  module Composition
80
80
  extend ActiveSupport::Concern
81
81
 
82
- COMPONENT_METHOD_NAME = "%s_component"
83
-
84
-
85
82
  included do
83
+ # Declares Base.component, for declaring child componets, and Base#components, which returns a [Hash] of all component configs by name
84
+ declare_dsl_for :components
86
85
 
87
- # Returns registered components
88
- class_attribute :registered_components
89
- self.registered_components = []
90
-
91
- # @!method Foobar
92
86
  # Loads a component on browser's request. Every Netzke component gets this endpoint.
93
87
  # <tt>params</tt> should contain:
94
88
  # * <tt>:cache</tt> - an array of component classes cached at the browser
@@ -112,44 +106,6 @@ module Netzke::Core
112
106
 
113
107
  end # included
114
108
 
115
- module ClassMethods
116
-
117
- # Declares a child (nested) component.
118
- # @param name [Symbol] component name
119
- # @param block [Proc] config block
120
- # @example
121
- # component :users do |c|
122
- # c.klass = Netzke::Basepack::Grid
123
- # c.modul = "User"
124
- # end
125
- def component(name, &block)
126
- self.registered_components |= [name]
127
-
128
- method_name = COMPONENT_METHOD_NAME % name
129
- if block_given?
130
- define_method(method_name, &block)
131
- else
132
- define_method(method_name) do |component_config|
133
- component_config
134
- end
135
- end
136
- end
137
- end
138
-
139
- # @return [Hash] component configs by name
140
- def components
141
- @components ||= self.class.registered_components.inject({}) do |out, name|
142
- component_config = Netzke::Core::ComponentConfig.new(name)
143
- send(COMPONENT_METHOD_NAME % name, component_config)
144
- component_config.set_defaults!
145
- if component_config.excluded
146
- out.merge(name.to_sym => {excluded: true})
147
- else
148
- out.merge(name.to_sym => component_config)
149
- end
150
- end
151
- end
152
-
153
109
  # @return [Hash] configs of eagerly loaded components by name
154
110
  def eagerly_loaded_components
155
111
  @eagerly_loaded_components ||= components.select{|k,v| components_in_config.include?(k) || v[:eager_loading]}
@@ -163,30 +119,18 @@ module Netzke::Core
163
119
  # Called when the method_missing tries to processes a non-existing component. Override when needed.
164
120
  def component_missing(aggr)
165
121
  flash :error => "Unknown component #{aggr} for #{name}"
166
- {:feedback => @flash}.to_nifty_json
122
+ {:feedback => @flash}.netzke_jsonify.to_json
167
123
  end
168
124
 
169
125
  # Recursively instantiates a child 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"
170
126
  # @param name [Symbol] component name
171
127
  def component_instance(name)
172
- raise ArgumentError, "No component '#{name.inspect}' defined for '#{self.js_id}'" if !name.present?
173
-
174
- @component_instance_cache ||= {}
175
- @component_instance_cache[name] ||= begin
176
- composite = self
177
- name.to_s.split('__').each do |cmp|
178
- cmp = cmp.to_sym
179
-
180
- component_config = composite.components[cmp]
181
- raise ArgumentError, "No component '#{cmp}' defined for '#{composite.js_id}'" if component_config.nil? || component_config[:excluded]
182
-
183
- klass = component_config[:klass]
184
-
185
- instance_config = component_config.merge(:name => cmp)
186
-
187
- composite = klass.new(instance_config, composite) # params: config, parent
188
- end
189
- composite
128
+ @_component_instance ||= {} # memoization
129
+ @_component_instance[name] ||= name.to_s.split('__').inject(self) do |out, cmp_name|
130
+ cmp_config = out.components[cmp_name.to_sym]
131
+ raise ArgumentError, "No component '#{cmp_name}' defined for '#{out.js_id}'" if cmp_config.nil? || cmp_config[:excluded]
132
+ cmp_config[:name] = cmp_name
133
+ cmp_config[:klass].new(cmp_config, out)
190
134
  end
191
135
  end
192
136
 
@@ -218,57 +162,19 @@ module Netzke::Core
218
162
  end
219
163
  end
220
164
 
221
- protected
222
-
223
- # During normalization of the config object, this method is being called with each item found (recursively) in there.
224
- # For example, symbols representing nested child components get replaced with a proper config hash. Same goes for actions.
225
- # Override to do any additional checks/enhancements. See, for example, +Netzke::Basepack::WrapLazyLoaded+.
226
- # @return [Object] extended item
227
165
  def extend_item(item)
228
- # in a situation of action and component being equally named, action will take precedence
229
-
230
- if item.is_a?(Symbol) && item_config = actions[item]
231
- item = {netzke_action: item}
232
- elsif item.is_a?(Symbol) && item_config = components[item]
233
- item = {netzke_component: item}
234
- end
235
-
236
- item[:excluded] = true if item_config && item_config[:excluded]
237
-
238
- if item.is_a?(Hash)
239
- return nil if item[:excluded] # it'll get compacted away by Array#deep_map
240
-
241
- # replace the `component` and `action` keys with `netzke_component` and `netzke_action`, which will be looked for at the JS side
242
- item[:netzke_action] = item.delete(:action) if item[:action]
243
- item[:netzke_component] = item.delete(:component) if item[:component]
244
-
245
- @components_in_config << item[:netzke_component] if item[:netzke_component] && item[:eager_loading] != false
246
- end
247
-
248
- item
166
+ item = detect_and_normalize(:component, item)
167
+ @components_in_config << item[:netzke_component] if include_component?(item)
168
+ super item
249
169
  end
250
170
 
251
171
  private
252
172
 
253
- # We'll build a couple of useful instance variables here:
254
- #
255
- # +components_in_config+ - an array of components (by name) referred in items
256
- # +normalized_config+ - a config that has all the config extensions applied
257
- def normalize_config
258
- @components_in_config = []
259
- @normalized_config = config.dup.tap do |c|
260
- c.each_pair do |k,v|
261
- c.delete(k) if self.class.server_side_config_options.include?(k.to_sym)
262
- c[k] = v.deep_map{|el| extend_item(el)} if v.is_a?(Array)
263
- end
264
- end
265
- end
266
-
267
- # @return [Hash] config with all placeholders (like child components referred by symbols) expanded
268
- def normalized_config
269
- # make sure we call normalize_config first
270
- @normalized_config || (normalize_config || true) && @normalized_config
173
+ def include_component?(cmp_config)
174
+ cmp_config.is_a?(Hash) &&
175
+ cmp_config[:netzke_component] &&
176
+ cmp_config[:eager_loading] != false &&
177
+ !cmp_config[:excluded]
271
178
  end
272
-
273
179
  end
274
180
  end