luca 0.9.8 → 0.9.9

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 (310) hide show
  1. data/CHANGELOG +49 -0
  2. data/Gemfile +8 -1
  3. data/Gemfile.lock +97 -53
  4. data/Guardfile +3 -25
  5. data/README.md +5 -16
  6. data/ROADMAP +15 -9
  7. data/Rakefile +24 -75
  8. data/app.rb +10 -42
  9. data/app/assets/javascripts/luca/basic.coffee +1 -1
  10. data/app/assets/javascripts/luca/components/application.coffee +187 -104
  11. data/app/assets/javascripts/luca/components/collection_view.coffee +115 -51
  12. data/app/assets/javascripts/luca/components/controller.coffee +87 -10
  13. data/app/assets/javascripts/luca/components/fields/base.coffee +74 -13
  14. data/app/assets/javascripts/luca/components/fields/button_field.coffee +60 -13
  15. data/app/assets/javascripts/luca/components/fields/checkbox_array.coffee +12 -7
  16. data/app/assets/javascripts/luca/components/fields/select_field.coffee +82 -23
  17. data/app/assets/javascripts/luca/components/fields/text_area_field.coffee +25 -10
  18. data/app/assets/javascripts/luca/components/fields/text_field.coffee +9 -3
  19. data/app/assets/javascripts/luca/components/form_view.coffee +105 -33
  20. data/app/assets/javascripts/luca/components/grid_layout_view.coffee +42 -0
  21. data/app/assets/javascripts/luca/components/index.coffee +6 -0
  22. data/app/assets/javascripts/luca/components/nav_bar.coffee +60 -6
  23. data/app/assets/javascripts/luca/components/page.coffee +70 -0
  24. data/app/assets/javascripts/luca/components/simple_collection_view.coffee +10 -0
  25. data/app/assets/javascripts/luca/components/table_view.coffee +7 -3
  26. data/app/assets/javascripts/luca/components/table_view_scrollable.coffee +23 -0
  27. data/app/assets/javascripts/luca/concerns/collection_event_bindings.coffee +4 -1
  28. data/app/assets/javascripts/luca/concerns/development_tool_helpers.coffee +23 -14
  29. data/app/assets/javascripts/luca/concerns/dom_helpers.coffee +2 -2
  30. data/app/assets/javascripts/luca/concerns/filterable.coffee +8 -11
  31. data/app/assets/javascripts/luca/concerns/form_model_bindings.coffee +20 -0
  32. data/app/assets/javascripts/luca/concerns/modal_view.coffee +40 -15
  33. data/app/assets/javascripts/luca/concerns/query_collection_bindings.coffee +7 -1
  34. data/app/assets/javascripts/luca/concerns/state_model.coffee +40 -26
  35. data/app/assets/javascripts/luca/concerns/templating.coffee +3 -1
  36. data/app/assets/javascripts/luca/config.coffee +5 -0
  37. data/app/assets/javascripts/luca/containers/card_view.coffee +87 -52
  38. data/app/assets/javascripts/luca/containers/container.coffee +305 -108
  39. data/app/assets/javascripts/luca/containers/modal_view.coffee +9 -9
  40. data/app/assets/javascripts/luca/containers/page_controller.coffee +25 -0
  41. data/app/assets/javascripts/luca/containers/panel_toolbar.coffee +5 -6
  42. data/app/assets/javascripts/luca/containers/tab_view.coffee +19 -10
  43. data/app/assets/javascripts/luca/containers/viewport.coffee +12 -16
  44. data/app/assets/javascripts/luca/core/collection.coffee +19 -5
  45. data/app/assets/javascripts/luca/core/events.coffee +5 -5
  46. data/app/assets/javascripts/luca/core/model.coffee +1 -1
  47. data/app/assets/javascripts/luca/core/panel.coffee +18 -6
  48. data/app/assets/javascripts/luca/core/registry/component_definition.coffee +2 -1
  49. data/app/assets/javascripts/luca/core/registry/meta_data.coffee +2 -0
  50. data/app/assets/javascripts/luca/core/registry/registry.coffee +14 -11
  51. data/app/assets/javascripts/luca/core/templates.coffee +5 -1
  52. data/app/assets/javascripts/luca/core/view.coffee +200 -47
  53. data/app/assets/javascripts/luca/dependencies.coffee +2 -0
  54. data/app/assets/javascripts/luca/development/code_sync_manager.coffee +173 -0
  55. data/app/assets/javascripts/luca/development/component.coffee +76 -0
  56. data/app/assets/javascripts/luca/development/components.coffee +57 -0
  57. data/app/assets/javascripts/luca/development/console.coffee +1 -1
  58. data/app/assets/javascripts/luca/development/index.coffee +4 -1
  59. data/app/assets/javascripts/luca/framework.coffee +7 -3
  60. data/app/assets/javascripts/luca/index.coffee +2 -1
  61. data/app/assets/javascripts/luca/managers/collection_manager.coffee +2 -3
  62. data/app/assets/javascripts/luca/managers/index.coffee +1 -1
  63. data/app/assets/javascripts/luca/managers/socket_manager.coffee +31 -8
  64. data/app/assets/javascripts/luca/templates/components/nav_bar.jst.ejs +16 -1
  65. data/app/assets/javascripts/luca/templates/containers/tab_view.jst.ejs +1 -1
  66. data/app/assets/javascripts/luca/util/index.coffee +1 -0
  67. data/app/assets/javascripts/luca/util/keybindings.coffee +24 -0
  68. data/app/assets/javascripts/luca/util/logging.coffee +15 -0
  69. data/app/assets/javascripts/luca/util/luca.coffee +9 -1
  70. data/app/assets/stylesheets/luca/components/table_view.scss +85 -0
  71. data/app/assets/stylesheets/luca/components/viewport.scss +0 -4
  72. data/app/assets/stylesheets/luca/containers/container.scss +8 -0
  73. data/app/assets/stylesheets/luca/index.css +2 -2
  74. data/bin/luca +14 -0
  75. data/config.ru +1 -2
  76. data/docs/framework.json +1 -0
  77. data/docs/luca-framework-documentation.js +1 -0
  78. data/docs/{application.md → old/application.md} +0 -0
  79. data/docs/{collection.md → old/collection.md} +0 -0
  80. data/docs/{collection_manager.md → old/collection_manager.md} +0 -0
  81. data/docs/{container_philosophy.md → old/container_philosophy.md} +0 -0
  82. data/docs/{event_binding_helpers.md → old/event_binding_helpers.md} +0 -0
  83. data/docs/{method_caching_and_computed_properties.md → old/method_caching_and_computed_properties.md} +0 -0
  84. data/docs/{view.md → old/view.md} +0 -0
  85. data/lib/generators/luca/application/templates/javascripts/dependencies.coffee +2 -5
  86. data/lib/guard/luca.rb +84 -0
  87. data/lib/luca.rb +25 -1
  88. data/lib/luca/asset_compiler.rb +117 -0
  89. data/lib/luca/cli.rb +68 -0
  90. data/lib/luca/cli/generate.rb +37 -0
  91. data/lib/luca/cli/server.rb +20 -0
  92. data/lib/luca/cli/sync.rb +40 -0
  93. data/lib/luca/cli/watch.rb +16 -0
  94. data/lib/luca/collection.rb +64 -0
  95. data/lib/luca/collection/endpoint.rb +38 -0
  96. data/lib/luca/collection/file_backend.rb +121 -0
  97. data/lib/luca/collection/redis_backend.rb +153 -0
  98. data/lib/luca/compiled_asset.rb +61 -0
  99. data/lib/luca/component_definition.rb +356 -0
  100. data/lib/luca/luca_application.rb +258 -0
  101. data/lib/luca/project.rb +73 -0
  102. data/lib/luca/project_harness.rb +96 -0
  103. data/lib/luca/rails.rb +5 -3
  104. data/lib/luca/rails/engine.rb +8 -0
  105. data/lib/luca/rails/version.rb +1 -2
  106. data/lib/luca/server.rb +7 -0
  107. data/lib/luca/stylesheet.rb +35 -0
  108. data/lib/luca/template.rb +2 -0
  109. data/lib/luca/template_asset.rb +64 -0
  110. data/lib/luca/version.rb +3 -0
  111. data/lib/luca/watcher.rb +72 -0
  112. data/lib/railties/luca/tasks.rake +7 -0
  113. data/site/.bundle/config +2 -0
  114. data/site/.gitignore +5 -0
  115. data/site/.rvmrc +1 -0
  116. data/site/CHANGELOG.md +41 -0
  117. data/site/DOCS.md +41 -0
  118. data/site/Gemfile +8 -0
  119. data/site/Gemfile.lock +134 -0
  120. data/site/LICENSE.md +19 -0
  121. data/site/config.rb +84 -0
  122. data/site/helpers/site_helpers.rb +20 -0
  123. data/site/html5bp-docs/README.md +38 -0
  124. data/site/html5bp-docs/contribute.md +104 -0
  125. data/site/html5bp-docs/crossdomain.md +21 -0
  126. data/site/html5bp-docs/css.md +135 -0
  127. data/site/html5bp-docs/extend.md +507 -0
  128. data/site/html5bp-docs/faq.md +77 -0
  129. data/site/html5bp-docs/htaccess.md +323 -0
  130. data/site/html5bp-docs/html.md +170 -0
  131. data/site/html5bp-docs/js.md +31 -0
  132. data/site/html5bp-docs/misc.md +25 -0
  133. data/site/html5bp-docs/usage.md +109 -0
  134. data/site/readme.md +47 -0
  135. data/site/source/.htaccess +540 -0
  136. data/site/source/404.html +157 -0
  137. data/site/source/app/assets/javascripts/dependencies.js.coffee +6 -0
  138. data/site/source/app/assets/javascripts/docs-docs.js +1 -0
  139. data/site/source/app/assets/javascripts/docs/application.coffee +64 -0
  140. data/site/source/app/assets/javascripts/docs/collections/docs_documentation.coffee +17 -0
  141. data/site/source/app/assets/javascripts/docs/collections/github_repositories.coffee +7 -0
  142. data/site/source/app/assets/javascripts/docs/collections/index.coffee +1 -0
  143. data/site/source/app/assets/javascripts/docs/collections/luca_documentation.coffee +17 -0
  144. data/site/source/app/assets/javascripts/docs/collections/public_gists.coffee +4 -0
  145. data/site/source/app/assets/javascripts/docs/config.coffee +5 -0
  146. data/site/source/app/assets/javascripts/docs/index.coffee +12 -0
  147. data/site/source/app/assets/javascripts/docs/lib/router.coffee +3 -0
  148. data/{spec/components/application_spec.coffee → site/source/app/assets/javascripts/docs/lib/util.coffee} +0 -0
  149. data/site/source/app/assets/javascripts/docs/models/component.coffee +99 -0
  150. data/site/source/app/assets/javascripts/docs/models/github_repository.coffee +3 -0
  151. data/site/source/app/assets/javascripts/docs/models/index.coffee +1 -0
  152. data/site/source/app/assets/javascripts/docs/templates/component_documentation.jst.ejs +55 -0
  153. data/site/source/app/assets/javascripts/docs/templates/examples_browser/overview.jst.ejs +4 -0
  154. data/site/source/app/assets/javascripts/docs/templates/examples_browser/selector.jst.ejs +11 -0
  155. data/site/source/app/assets/javascripts/docs/templates/github_repository.jst.ejs +4 -0
  156. data/site/source/app/assets/javascripts/docs/templates/layouts/main.jst.ejs +4 -0
  157. data/site/source/app/assets/javascripts/docs/templates/left_navigation.jst.ejs +5 -0
  158. data/site/source/app/assets/javascripts/docs/templates/pages/getting_started.jst.ejs +78 -0
  159. data/site/source/app/assets/javascripts/docs/templates/pages/home.jst.ejs +57 -0
  160. data/site/source/app/assets/javascripts/docs/views/components/code_editor.coffee +45 -0
  161. data/{spec/components/collection_loader_view_spec.coffee → site/source/app/assets/javascripts/docs/views/components/code_editor/index.coffee} +0 -0
  162. data/site/source/app/assets/javascripts/docs/views/components/component_documentation.coffee +72 -0
  163. data/site/source/app/assets/javascripts/docs/views/index.coffee +3 -0
  164. data/site/source/app/assets/javascripts/docs/views/pages/browse_source.coffee +46 -0
  165. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/details.coffee +37 -0
  166. data/site/source/app/assets/javascripts/docs/views/pages/browse_source/list.coffee +31 -0
  167. data/site/source/app/assets/javascripts/docs/views/pages/component_editor.coffee +10 -0
  168. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser.coffee +102 -0
  169. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/docs.coffee +12 -0
  170. data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/source.coffee +13 -0
  171. data/site/source/app/assets/javascripts/docs/views/pages/home.coffee +10 -0
  172. data/site/source/app/assets/javascripts/docs/views/views/api_browser/index.coffee +43 -0
  173. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/grid_layout_view_example.coffee +14 -0
  174. data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/table_view_example.coffee +39 -0
  175. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/basic_example.coffee +38 -0
  176. data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/complex_layout.coffee +110 -0
  177. data/site/source/app/assets/javascripts/docs/views/views/top_navigation.coffee +6 -0
  178. data/site/source/app/assets/javascripts/luca-docs.js +1 -0
  179. data/site/source/app/assets/javascripts/luca-framework-documentation.js +1 -0
  180. data/site/source/app/assets/javascripts/site.js.coffee +4 -0
  181. data/site/source/app/assets/javascripts/vendor/codemirror.js +4786 -0
  182. data/site/source/app/assets/javascripts/vendor/coffeescript.js +346 -0
  183. data/site/source/app/assets/javascripts/vendor/css.js +465 -0
  184. data/site/source/app/assets/javascripts/vendor/htmlmixed.js +84 -0
  185. data/site/source/app/assets/javascripts/vendor/javascript.js +422 -0
  186. data/site/source/app/assets/javascripts/vendor/js-beautify.js +1353 -0
  187. data/site/source/app/assets/javascripts/vendor/modernizr-2.6.1.min.js +4 -0
  188. data/site/source/app/assets/javascripts/vendor/vim.js +2511 -0
  189. data/site/source/app/assets/stylesheets/docs/api-browser.css.scss +5 -0
  190. data/site/source/app/assets/stylesheets/docs/application.css.scss +35 -0
  191. data/site/source/app/assets/stylesheets/docs/browse-source.css.scss +5 -0
  192. data/site/source/app/assets/stylesheets/docs/scrollable-table.css.scss +5 -0
  193. data/site/source/app/assets/stylesheets/site.css.scss +2 -0
  194. data/site/source/app/assets/stylesheets/vendor/codemirror.css +240 -0
  195. data/site/source/app/assets/stylesheets/vendor/prettify-tomorrow-night-bright.css +160 -0
  196. data/site/source/app/assets/stylesheets/vendor/twilight.css +26 -0
  197. data/site/source/crossdomain.xml +15 -0
  198. data/site/source/documentation.html.haml +1 -0
  199. data/site/source/favicon_base.png +0 -0
  200. data/site/source/humans.txt +15 -0
  201. data/site/source/images/background.png +0 -0
  202. data/site/source/images/middleman.png +0 -0
  203. data/site/source/index.html.haml +1 -0
  204. data/site/source/layouts/layout.haml +55 -0
  205. data/site/source/readme.md +63 -0
  206. data/site/source/robots.txt +3 -0
  207. data/spec/{components/grid_view_spec.coffee → javascripts/components/application_spec.coffee} +0 -0
  208. data/spec/{components/pagination_control_spec.coffee → javascripts/components/collection_loader_view_spec.coffee} +0 -0
  209. data/spec/{components → javascripts/components}/collection_view_spec.coffee +1 -1
  210. data/spec/{components → javascripts/components}/controller_spec.coffee +0 -0
  211. data/spec/{components → javascripts/components}/fields/checkbox_array_spec.coffee +0 -0
  212. data/spec/javascripts/components/form_view_spec.coffee +162 -0
  213. data/spec/{components/record_manager_spec.coffee → javascripts/components/grid_view_spec.coffee} +0 -0
  214. data/spec/{components → javascripts/components}/multi_collection_view_spec.coffee +0 -0
  215. data/spec/{components/template_spec.coffee → javascripts/components/pagination_control_spec.coffee} +0 -0
  216. data/spec/{concerns/paginatable_spec.coffee → javascripts/components/record_manager_spec.coffee} +0 -0
  217. data/spec/{components → javascripts/components}/table_view_spec.coffee +0 -0
  218. data/spec/{containers/modal_view_spec.coffee → javascripts/components/template_spec.coffee} +0 -0
  219. data/spec/{concerns → javascripts/concerns}/collection_event_bindings_spec.coffee +0 -0
  220. data/spec/{concerns → javascripts/concerns}/dom_helpers_spec.coffee +0 -0
  221. data/spec/{concerns → javascripts/concerns}/filterable_spec.coffee +0 -0
  222. data/spec/{concerns → javascripts/concerns}/model_presenter_spec.coffee +0 -0
  223. data/spec/{containers/panel_view_spec.coffee → javascripts/concerns/paginatable_spec.coffee} +0 -0
  224. data/spec/{concerns → javascripts/concerns}/state_model_spec.coffee +5 -0
  225. data/spec/javascripts/containers/card_view_spec.coffee +108 -0
  226. data/spec/{containers/tab_view_spec.coffee → javascripts/containers/modal_view_spec.coffee} +0 -0
  227. data/spec/{containers/viewport_spec.coffee → javascripts/containers/panel_view_spec.coffee} +0 -0
  228. data/spec/{core/observer_spec.coffee → javascripts/containers/tab_view_spec.coffee} +0 -0
  229. data/spec/{managers/socket_manager_spec.coffee → javascripts/containers/viewport_spec.coffee} +0 -0
  230. data/spec/{core → javascripts/core}/collection_spec.coffee +1 -1
  231. data/spec/{core → javascripts/core}/concerns_spec.coffee +0 -0
  232. data/spec/{core → javascripts/core}/container_spec.coffee +0 -0
  233. data/spec/{core → javascripts/core}/define_spec.coffee +0 -0
  234. data/spec/{core → javascripts/core}/events_spec.coffee +0 -0
  235. data/spec/{core → javascripts/core}/field_spec.coffee +0 -0
  236. data/spec/{core → javascripts/core}/framework_spec.coffee +0 -0
  237. data/spec/{core → javascripts/core}/model_spec.coffee +0 -0
  238. data/spec/javascripts/core/observer_spec.coffee +0 -0
  239. data/spec/{core → javascripts/core}/util_spec.coffee +0 -0
  240. data/spec/{core → javascripts/core}/view_spec.coffee +51 -39
  241. data/spec/{dependencies → javascripts/dependencies}/index.coffee +0 -0
  242. data/spec/{dependencies → javascripts/dependencies}/jasmine-html.js +0 -0
  243. data/spec/{dependencies → javascripts/dependencies}/jasmine.js +0 -0
  244. data/spec/{dependencies → javascripts/dependencies}/sinon.js +0 -0
  245. data/spec/{helper.coffee → javascripts/helper.coffee} +0 -0
  246. data/spec/{managers → javascripts/managers}/collection_manager_spec.coffee +0 -0
  247. data/spec/javascripts/managers/socket_manager_spec.coffee +0 -0
  248. data/spec/lib/component_definition_spec.rb +63 -0
  249. data/spec/lib/input_compiler_spec.rb +9 -0
  250. data/spec/lib/luca_application_spec.rb +30 -0
  251. data/spec/support/fixtures/application.coffee +45 -0
  252. data/spec/support/fixtures/component.coffee +34 -0
  253. data/tutorials/component-definitions.md +0 -0
  254. data/tutorials/component-definitions/01_intro.md +0 -0
  255. data/tutorials/component-driven-design.md +140 -0
  256. data/tutorials/structure-of-a-project.md +63 -0
  257. data/vendor/assets/javascripts/backbone-min.js +37 -33
  258. data/vendor/assets/javascripts/backbone-query.min.js +1 -1
  259. data/vendor/assets/javascripts/hogan.js +707 -0
  260. data/vendor/assets/javascripts/jquery.js +5 -4
  261. data/vendor/assets/javascripts/keymaster.min.js +4 -0
  262. data/vendor/assets/javascripts/luca-dependencies.min.js +8 -0
  263. data/vendor/assets/javascripts/luca-development.min.js +1 -0
  264. data/vendor/assets/javascripts/luca-spec.js +6 -6
  265. data/vendor/assets/javascripts/luca-ui.js +7386 -0
  266. data/vendor/assets/javascripts/luca-ui.min.js +5 -0
  267. data/vendor/assets/javascripts/luca.full.min.js +12 -0
  268. data/vendor/assets/javascripts/luca.min.js +5 -0
  269. data/vendor/assets/javascripts/underscore-min.js +1 -5
  270. data/vendor/assets/javascripts/underscore-string.min.js +1 -1
  271. data/vendor/assets/stylesheets/luca-components.css +202 -0
  272. data/vendor/assets/stylesheets/luca-development.css +23 -0
  273. data/vendor/assets/stylesheets/luca-ui.css +198 -0
  274. metadata +324 -94
  275. data/app/assets/javascripts/luca/components/base_toolbar.coffee +0 -17
  276. data/app/assets/javascripts/luca/components/form_button_toolbar.coffee +0 -28
  277. data/app/assets/javascripts/luca/components/grid_view.coffee +0 -269
  278. data/app/assets/javascripts/luca/components/page_controller.coffee +0 -7
  279. data/app/assets/javascripts/luca/components/template.coffee +0 -5
  280. data/app/assets/javascripts/luca/components/toolbar_dialog.coffee +0 -25
  281. data/lib/luca/code_browser.rb +0 -55
  282. data/lib/luca/command_line.rb +0 -69
  283. data/lib/luca/component_documentation.rb +0 -72
  284. data/site/assets/bootstrap.min.js +0 -7
  285. data/site/assets/dependencies.js +0 -94
  286. data/site/assets/glyphicons-halflings-white.png +0 -0
  287. data/site/assets/glyphicons-halflings.png +0 -0
  288. data/site/assets/luca-ui-bootstrap.css +0 -1331
  289. data/site/assets/luca-ui-bootstrap.js +0 -9
  290. data/site/assets/luca-ui-development-tools.css +0 -234
  291. data/site/assets/luca-ui-development-tools.js +0 -18561
  292. data/site/assets/luca-ui-development-tools.min.js +0 -15
  293. data/site/assets/luca-ui-full.min.js +0 -8
  294. data/site/assets/luca-ui.min.js +0 -4
  295. data/site/assets/sandbox.css +0 -62
  296. data/site/assets/sandbox.js +0 -469
  297. data/site/docs/application.html +0 -41
  298. data/site/docs/caching.html +0 -43
  299. data/site/docs/collection.html +0 -75
  300. data/site/docs/collection_manager.html +0 -71
  301. data/site/docs/containers.html +0 -118
  302. data/site/docs/events.html +0 -153
  303. data/site/docs/view.html +0 -128
  304. data/site/img/glyphicons-halflings-white.png +0 -0
  305. data/site/img/glyphicons-halflings.png +0 -0
  306. data/site/index.html +0 -20
  307. data/site/source-map.js +0 -1
  308. data/spec/components/form_view_spec.coffee +0 -84
  309. data/spec/containers/card_view_spec.coffee +0 -50
  310. data/spec/luca-spec.coffee +0 -9
@@ -12,7 +12,7 @@ if window.JST?
12
12
 
13
13
  # optionally, passing in variables will compile the template for you, instead
14
14
  # of returning a reference to the function which you would then call yourself
15
- Luca.template = (template_name, variables)->
15
+ Luca.template = (template_name, variables, partials)->
16
16
  window.JST ||= {}
17
17
 
18
18
  if _.isFunction(template_name)
@@ -34,6 +34,10 @@ Luca.template = (template_name, variables)->
34
34
 
35
35
  template = luca || jst
36
36
 
37
+ if template instanceof Hogan.template
38
+ if variables?
39
+ return template.render(variables, partials)
40
+
37
41
  return template(variables) if variables?
38
42
 
39
43
  template
@@ -1,16 +1,89 @@
1
+ # `Luca.View` is an enhanced `Backbone.View` which provides common patterns for view components,
2
+ # and various helper methods and configuration conventions.
3
+ #
4
+ # #### Instance caching / naming
5
+ #
6
+ # If you provide a `@name` property to your views, they will be accessible by that property
7
+ # using the Application helper.
8
+ #
9
+ # view = new Luca.View(name:"my_view")
10
+ # Luca("my_view") === view
11
+ #
12
+ # #### CSS @className conventions
13
+ #
14
+ # In order to make it easier to componentize your views, extending from `Luca.View` will
15
+ # enable CSS class based inheritance based on the names of the view class.
16
+ #
17
+ # ##### For Example:
18
+ #
19
+ # base = Luca.register "App.views.BaseViewClass"
20
+ # base.extends "Luca.View"
21
+ # base.defines
22
+ # className: "some-other-class"
23
+ #
24
+ # child = Luca.register "App.views.ChildViewClass"
25
+ # child.extends "App.views.BaseViewClass"
26
+ # child.defines
27
+ # myClasses: ()->
28
+ # @$el.attr('class')
29
+ #
30
+ # view = new App.views.ChildViewClass()
31
+ # view.myClasses() #=> "app-base-view-class app-child-view-class some-other-class"
32
+ #
33
+ # This establishes a convention for css class names, and allows you to componetize your css
34
+ # along with the component by joining them based on the name of your view class. When using
35
+ # Sass scoping / nesting it fits very nicely together.
36
+ #
37
+ # #### Internal state machine
38
+ #
39
+ # Any `Luca.View` class which defines a `@stateful` property will automatically generate a
40
+ # `@state` model that can be used to get/set attributes on the view as well as bind to change events on these attributes.
41
+ #
42
+ # This gives your views a dedicated place to store state, and you can bind to your data models separately
43
+ # and update the DOM without confusing the two.
44
+ #
45
+ # statefulView = Luca.register "App.views.StatefulView"
46
+ # statefulView.extends "Luca.View"
47
+ #
48
+ # statefulView.defines
49
+ # # Passing an object allows you to set default values on the @state model.
50
+ # stateful:
51
+ # attribute: "value"
52
+ #
53
+ # # Whenever the attribute specified changes, call the specified method.
54
+ # stateChangeEvents:
55
+ # "attribute" : "onAttributeChange"
56
+ #
57
+ # onAttributeChange: (stateMachine, attributeValue)->
58
+ # @doSomethingWhenAttributeChanges()
59
+ #
60
+ # If this type of declarative style isn't your thing, you can still bind to events in code:
61
+ #
62
+ # view = new App.views.StatefulView()
63
+ # view.on "state:change:attribute", (stateMachine, attributeValue)=> @$el.html("New Attribute: #")
64
+ # view.set "attribute", "something"
65
+ #
66
+ # #### Event binding helpers
67
+ #
68
+ # In addition to the `@stateChangeEvent` bindings documented above, you have available
69
+ # to you similar configuration helpers for binding to events emitted by the singletons:
70
+ #
71
+ # - `Luca.Application` via `@applicationEvents`
72
+ # - `Luca.CollectionManager` via `@collectionEvents`
73
+ # - `Luca.SocketManager` via `@socketEvents`
1
74
  view = Luca.register "Luca.View"
2
-
3
75
  view.extends "Backbone.View"
4
76
 
5
77
  # includes are extensions to the prototype, and have no special behavior
6
78
  view.includes "Luca.Events",
7
- "Luca.concerns.DomHelpers"
79
+ "Luca.concerns.DomHelpers",
80
+ "Luca.concerns.DevelopmentToolHelpers"
8
81
 
9
82
  # concerns are includes with special property / method conventions
10
83
  # which customize the components through the use of __initializer and
11
84
  # __included method names. These will be called every time an instance
12
85
  # is created, and the first time the mixin is used to enhance a component.
13
- view.mixesIn "DomHelpers",
86
+ view.mixesIn "DomHelpers",
14
87
  "Templating",
15
88
  "EnhancedProperties",
16
89
  "CollectionEventBindings",
@@ -18,10 +91,10 @@ view.mixesIn "DomHelpers",
18
91
  "StateModel"
19
92
 
20
93
  # Luca.View classes have the concept of special events called hooks
21
- # which allow you to tap into the lifecycle events of your view to
94
+ # which allow you to tap into the lifecycle events of your view to
22
95
  # customize their behavior. This is especially useful in subclasses.
23
96
  #
24
- # You can utilize a @hook method by camelcasing the triggers defined below:
97
+ # You can utilize a @hook method by camelcasing the triggers defined below:
25
98
  view.triggers "before:initialize",
26
99
  "after:initialize",
27
100
  "before:render",
@@ -30,84 +103,163 @@ view.triggers "before:initialize",
30
103
  "activation",
31
104
  "deactivation"
32
105
 
106
+ view.publicConfiguration
107
+ # Specifying a `@name` for your views is useful for views which
108
+ # there will only be one instance. This allows you to reference
109
+ # the view instances by name using the application helper:
110
+ # Luca("my_view_name")
111
+ name: undefined
112
+
113
+ # Setting this property to true will automatically bind the context
114
+ # of your event handler methods to the instance of this view. This
115
+ # saves you from having to manually do:
116
+ #
117
+ # Luca.View.extend
118
+ # events:
119
+ # "click .one" : "oneHandler"
120
+ # "click .two" : "twoHandler"
121
+ # initialize: ()->
122
+ # _.bindAll(@, "oneHandler", "twoHandler")
123
+ #
124
+ # Instead:
125
+ #
126
+ # Luca.View.extend
127
+ # autoBindEventHandlers: true
128
+ # events:
129
+ # "click .one" : "oneHandler"
130
+ #
131
+ # Optionally, you can define an array of method names you want bound
132
+ # to this view:
133
+ #
134
+ # Luca.View.extend
135
+ # bindMethods:["oneHandler","twoHandler"]
136
+ #
137
+ autoBindEventHandlers: false
138
+
139
+ # Supplying configuration to `@_inheritEvents` will ensure that this configuration
140
+ # is present on views which extend from this view. In normal Backbone behavior
141
+ # the `@events` property can be overridden by views which extend, and this isn't
142
+ # always what you want from your component.
143
+ _inheritEvents: undefined
144
+
145
+
146
+
33
147
  # Luca.View decorates Backbone.View with some patterns and conventions.
34
- view.defines
148
+ view.publicMethods
35
149
  identifier: ()->
36
150
  (@displayName || @type ) + ":" + (@name || @role || @cid)
37
151
 
152
+ # Calls Backbone.View::remove, and removes the view from the
153
+ # instance cache. Triggers a "before:remove" event.
154
+ remove: ()->
155
+ @trigger("before:remove", @)
156
+ Luca.remove(@)
157
+ Backbone.View::remove.apply(@, arguments)
158
+
38
159
  initialize: (@options={})->
39
160
  @trigger "before:initialize", @, @options
40
161
 
41
162
  _.extend @, @options
42
163
 
43
164
  if @autoBindEventHandlers is true or @bindAllEvents is true
44
- bindAllEventHandlers.call(@)
165
+ bindAllEventHandlers.call(@)
45
166
 
46
167
  @cid = _.uniqueId(@name) if @name?
47
168
 
48
169
  @$el.attr("data-luca-id", @name || @cid)
49
-
170
+
50
171
  Luca.registry.cacheInstance( @cid, @ )
51
172
 
52
173
  @setupHooks _( Luca.View::hooks.concat( @hooks ) ).uniq()
53
174
 
54
175
  Luca.concern.setup.call(@)
55
176
 
56
- @delegateEvents()
57
-
177
+ @delegateEvents() unless _.isEmpty(@events)
178
+
58
179
  @trigger "after:initialize", @
59
180
 
60
181
  _.bindAll(@, @bindMethods...) if @bindMethods?.legth > 0
61
182
 
62
- #### Hooks or Auto Event Binding
63
- #
64
- # views which inherit from Luca.View can define hooks
65
- # or events which can be emitted from them. Automatically,
66
- # any functions on the view which are named according to the
67
- # convention will automatically get run.
68
- #
69
- # by default, all Luca.View classes come with the following:
70
- #
71
- # before:render : beforeRender()
72
- # after:render : afterRender()
73
- # after:initialize : afterInitialize()
74
- # first:activation : firstActivation()
75
- setupHooks: Luca.util.setupHooks
183
+ unless _.isEmpty(@_inheritEvents)
184
+ for eventId, handler of @_inheritEvents
185
+ @registerEvent(eventId, handler)
186
+
187
+
188
+ debug: (args...)->
189
+ if @debugMode is true or window.LucaDebugMode is true
190
+ args.unshift @identifier()
191
+ console.log args...
192
+
193
+ trigger: ()->
194
+ if Luca.enableGlobalObserver
195
+ if Luca.developmentMode is true or @observeEvents is true
196
+ Luca.ViewObserver ||= new Luca.Observer(type:"view")
197
+ Luca.ViewObserver.relay @, arguments
198
+
199
+ Backbone.View::trigger.apply @, arguments
200
+
201
+ # Backbone.View.prototype.make is removed in 0.9.10.
202
+ # As we happen to rely on this little utility heavily,
203
+ # we add it to Luca.View
204
+ make: (tagName, attributes, content)->
205
+ el = document.createElement(tagName);
206
+ if (attributes)
207
+ Backbone.$(el).attr(attributes)
208
+ if (content != null)
209
+ Backbone.$(el).html(content)
210
+
211
+ el
76
212
 
77
213
  registerEvent: (selector, handler)->
78
214
  @events ||= {}
79
- @events[ selector ] = handler
80
215
 
81
216
  if _.isObject(selector)
82
- _.extend(@events, selector)
83
-
217
+ @events = _.extend(@events, selector)
218
+ else
219
+ if _.isFunction(handler) || (_.isString(handler) && @[handler]?)
220
+ @events[selector] = handler
221
+
84
222
  @delegateEvents()
85
223
 
224
+ view.privateMethods
225
+ # Returns a reference to the class which this view is an instance of.
86
226
  definitionClass: ()->
87
227
  Luca.util.resolve(@displayName, window)?.prototype
88
228
 
89
- collections: ()->
229
+ # Returns a list of all of the collections which are properties on this view.
230
+ _collections: ()->
90
231
  Luca.util.selectProperties( Luca.isBackboneCollection, @ )
91
232
 
92
- models: ()->
233
+ # Returns a list of all of the models which are properties on this view.
234
+ _models: ()->
93
235
  Luca.util.selectProperties( Luca.isBackboneModel, @ )
94
236
 
95
- views: ()->
237
+ # Returns a list of all of the views which are properties on this view.
238
+ _views: ()->
96
239
  Luca.util.selectProperties( Luca.isBackboneView, @ )
97
240
 
98
- debug: (args...)->
99
- if @debugMode is true or window.LucaDebugMode is true
100
- args.unshift @identifier()
101
- console.log args...
102
-
103
- trigger: ()->
104
- if Luca.enableGlobalObserver
105
- if Luca.developmentMode is true or @observeEvents is true
106
- Luca.ViewObserver ||= new Luca.Observer(type:"view")
107
- Luca.ViewObserver.relay @, arguments
241
+ # views which inherit from Luca.View can define hooks
242
+ # or events which can be emitted from them. Automatically,
243
+ # any functions on the view which are named according to the
244
+ # convention will automatically get run.
245
+ #
246
+ # by default, all Luca.View classes come with the following:
247
+ #
248
+ # - before:render : beforeRender()
249
+ # - after:render : afterRender()
250
+ # - after:initialize : afterInitialize()
251
+ # - first:activation : firstActivation()
252
+ setupHooks: Luca.util.setupHooks
108
253
 
109
- Backbone.View.prototype.trigger.apply @, arguments
254
+ # In order to support some Luca apps which rely
255
+ # on Backbone.View.make.
256
+ view.afterDefinition ()->
257
+ if not Backbone.View::make?
258
+ Backbone.View::make = ()->
259
+ console.log "Backbone.View::make has been removed from backbone. You should use Luca.View::make instead."
260
+ Luca.View::make
110
261
 
262
+ view.register()
111
263
 
112
264
  Luca.View._originalExtend = Backbone.View.extend
113
265
 
@@ -115,12 +267,12 @@ Luca.View._originalExtend = Backbone.View.extend
115
267
  #
116
268
  # I will be removing this prior to 1.0. Optimizing for collection based
117
269
  # views does not belong in here, so the deferrable / collection binding stuff
118
- # needs to go.
270
+ # needs to go.
119
271
  #
120
272
  # Being able to defer rendering until the firing of an event on another object
121
273
  # is something that does ask for some syntactic sugar though, so need to rethink.
122
274
 
123
- Luca.View.renderStrategies =
275
+ Luca.View.renderStrategies =
124
276
  legacy: ( _userSpecifiedMethod )->
125
277
  view = @
126
278
  # if a view has a deferrable property set
@@ -132,10 +284,11 @@ Luca.View.renderStrategies =
132
284
  @deferrable = @collection
133
285
 
134
286
  target ||= @deferrable
135
- trigger = if @deferrable_event then @deferrable_event else Luca.View.deferrableEvent
287
+ trigger = if @deferrable_event then @deferrable_event else Luca.View.deferrableEvent
136
288
 
137
289
  deferred = ()->
138
290
  _userSpecifiedMethod.call(view)
291
+ @rendered = true
139
292
  view.trigger("after:render", view)
140
293
 
141
294
  view.defer(deferred).until(target, trigger)
@@ -155,6 +308,7 @@ Luca.View.renderStrategies =
155
308
  else
156
309
  @trigger "before:render", @
157
310
  _userSpecifiedMethod.apply(@, arguments)
311
+ @rendered = true
158
312
  @trigger "after:render", @
159
313
 
160
314
  return @
@@ -162,10 +316,9 @@ Luca.View.renderStrategies =
162
316
  improved: (_userSpecifiedMethod)->
163
317
  @trigger "before:render", @
164
318
 
165
-
166
319
  deferred = ()=>
167
320
  _userSpecifiedMethod.apply(@, arguments)
168
- @trigger "after:render", @
321
+ @trigger "after:render", @
169
322
 
170
323
  console.log "doing the improved one", @deferrable
171
324
 
@@ -203,7 +356,7 @@ Luca.View.renderWrapper = (definition)->
203
356
 
204
357
  bindAllEventHandlers = ()->
205
358
  for config in [@events, @componentEvents, @collectionEvents, @applicationEvents] when not _.isEmpty(config)
206
- bindEventHandlers.call(@, config)
359
+ bindEventHandlers.call(@, config)
207
360
 
208
361
  bindEventHandlers = (events={})->
209
362
  for eventSignature, handler of events
@@ -1,7 +1,9 @@
1
1
  #= require jquery
2
2
  #= require underscore-min
3
3
  #= require underscore-string.min
4
+ #= require hogan.js
4
5
  #= require backbone-min
5
6
  #= require backbone-query.min
6
7
  #= require bootstrap.min
8
+ #= require keymaster.min
7
9
  #= require_self
@@ -0,0 +1,173 @@
1
+ # The `Luca.CodeSyncManager` works along with the Guard adapter that ships with
2
+ # the ruby gem. This is still an experimental option at this point, but I use
3
+ # it regularly on all of my Luca projects and it allows me to develop my applications
4
+ # directly from my editor and rarely have the need to refresth the browser to work with
5
+ # javascript and css changes.
6
+ #
7
+ # #### Similar to LiveReload
8
+ # It is similar to projects like LiveReload, except that it knows a lot about the luca
9
+ # framework and application conventions and uses this knowledge to optimize live reloading
10
+ # behavior, avoiding the need to do full browser reloads. This typically doesn't work well
11
+ # with state heavy applications, since the browser reloading doesn't always construct application
12
+ # state exactly as you need it when you're making your css changes etc.
13
+ #
14
+ # #### 1) Add an entry to your Guardfile:
15
+ # guard 'luca' do
16
+ # watch(%r{^app/assets/stylesheets/(.+)}) do |match|
17
+ # path = match.last
18
+ # end
19
+
20
+ # watch(%r{^app/assets/javascripts/(.+)}) do |match|
21
+ # path = match.last
22
+ # end
23
+ # end
24
+ #
25
+ # #### 2) Add the `CodeSyncManager` to your development mode application.
26
+ # **Note:** This expect
27
+ # you to have a `Luca.SocketManager` capable backend such as faye or socket.io running. It
28
+ # handles the same configuration options as the `Luca.SocketManager` as well.
29
+ #
30
+ # app = Luca()
31
+ # app.codeSyncManager = new Luca.CodeSyncManager
32
+ # host: "//localhost:9292/faye"
33
+ # channel: "/changes"
34
+ # app.codeSyncManager.trigger("ready")
35
+ #
36
+ # #### 3) Run guard.
37
+ # Edit your files, watch your changes appear.
38
+ #
39
+ # ### Using the Syncpad
40
+ #
41
+ # The syncpad is a special naming convention for development scratch paper in your editor. A file
42
+ # named syncpad.coffee, syncpad.css.scss, syncpad.jst.ejs.haml, etc will be evaluated live when you change
43
+ # them in your editor. I personally use this to experiment with code / css and get immediate results without
44
+ # needing to refresh the browser.
45
+ codeManager = Luca.register "Luca.CodeSyncManager"
46
+ codeManager.extends "Luca.SocketManager"
47
+
48
+ codeManager.publicConfiguration
49
+ host: Luca.config.codeSyncHost || "//localhost:9292/faye"
50
+ namespace: "luca"
51
+ channel: Luca.config.codeSyncChannel || "/luca-code-sync"
52
+
53
+ codeManager.classMethods
54
+ setup: (options={})->
55
+ @codeSyncManager = new Luca.CodeSyncManager(options)
56
+ @codeSyncManager.trigger "ready"
57
+
58
+ codeManager.privateMethods
59
+ initialize: (@attributes={})->
60
+ unless @attributes.host?
61
+ _.extend(@attributes, host: (@host || Luca.config.codeSyncHost))
62
+
63
+ Luca.SocketManager::initialize.call(@, @attributes)
64
+ @bindToChannel()
65
+
66
+ start: ()->
67
+ @trigger "ready"
68
+
69
+ bindToChannel: ()->
70
+ if @client?
71
+ @client.subscribe @channel, ()=>
72
+ @onChangesNotification.apply(@, arguments)
73
+ else
74
+ @on "change:client", (socketManager, client)=>
75
+ @client.subscribe @channel, ()=>
76
+ @onChangesNotification.apply(@, arguments)
77
+
78
+ # changeData is a payload that gets sent over the socket
79
+ # whenever an asset that is being watched changes.
80
+ # it is different if the type of file is css or javascript.
81
+ onChangesNotification: (changeData={}, applicationName)->
82
+ return if _.isEmpty(changeData)
83
+ data = _( changeData ).values()[0] || {}
84
+
85
+ if data.type is "template"
86
+ @processTemplate(data)
87
+ @rerunSyncPad(data.type)
88
+
89
+ if data.type is "component_definition"
90
+ @processComponentDefinitionChange(data)
91
+ @processJavascriptChange(data)
92
+
93
+ _.delay ()=>
94
+ @rerunSyncPad(data.type)
95
+ , 25
96
+
97
+ if data.type is "javascript"
98
+ @processJavascriptChange(data)
99
+
100
+ if data.type is "stylesheet" and data?.path
101
+ @processStylesheetChange(data)
102
+
103
+ rerunSyncPad: ()->
104
+ if last = @get("last_syncpad_javascript_payload")
105
+ @processJavascriptChange(last)
106
+
107
+ processTemplate: (change={})->
108
+ fn = ()->
109
+ eval( change.contents )
110
+
111
+ fn.apply(window)
112
+
113
+ processComponentDefinitionChange: (change={})->
114
+ return if _.isEmpty(change)
115
+ @components ||= Luca.collections.Components.generate()
116
+
117
+ if change.class_name?
118
+ component = @components.findByClassName( change.class_name )
119
+
120
+ if component && change.source_file_contents?
121
+ component.set(source_file_contents: change.source_file_contents )
122
+
123
+ processJavascriptChange: (change={})->
124
+ return unless change?.compiled
125
+ existing = $("body script[data-path='#{ change.source }']")
126
+
127
+ # just to be clean
128
+ if existing.length > 1
129
+ existing.remove()
130
+
131
+ if change.source?.match(/syncpad/) and change?.compiled and true
132
+ @set("last_syncpad_javascript_payload", change)
133
+
134
+ script = @make("script", {"data-path": change.source, type:"text/javascript"}, change.compiled)
135
+ $('body').append(script)
136
+
137
+ processStylesheetChange: (change={})->
138
+ return if _.isEmpty(change)
139
+
140
+ if change.path?.match(/syncpad/) or Luca.config.codeSyncStylesheetMode is "single"
141
+ @syncStylesheet(change)
142
+ else
143
+ @replaceStylesheetAndEverythingAfter(change.path)
144
+
145
+ replaceStylesheetAndEverythingAfter: (path)->
146
+ stylesheet = path.replace('./app/assets/stylesheets', Luca.config.assetsUrlPrefix )
147
+ stylesheet = stylesheet.replace('.scss','')
148
+ existing = $("link[href*='#{ stylesheet }']")
149
+ parent = existing.parent()
150
+
151
+ return unless existing.length > 0
152
+
153
+ replaced = existing.clone()
154
+ comesAfter = existing.nextAll('link')
155
+ cloned = comesAfter.clone()
156
+
157
+ $(existing, comesAfter).remove()
158
+
159
+ parent.append( replaced )
160
+ parent.append( cloned )
161
+
162
+ syncStylesheet: (change)->
163
+ existing = $("head style[data-file='#{ change.path }']")
164
+
165
+ if existing.length > 0
166
+ existing.remove()
167
+
168
+ if change.compiled? or change.contents?
169
+ link = @make("style",{"data-file":change.path, type:"text/css"}, change.compiled || change.contents)
170
+ $('head').append( link )
171
+
172
+ codeManager.defines
173
+ make: Luca.View::make