Permalink
Browse files

Bringing back in JavaScriptMVC implementation based on #252. Note: we…

… need to reduce JMVC dep. bloat.
  • Loading branch information...
1 parent 70fa853 commit 75b9d7440acf165735b3fb760c9f0fed224549e7 @addyosmani addyosmani committed Dec 26, 2012
Showing with 35,716 additions and 1 deletion.
  1. +1 −1 index.html
  2. +24 −0 labs/architecture-examples/javascriptmvc/jquery/README
  3. +146 −0 labs/architecture-examples/javascriptmvc/jquery/build.js
  4. +130 −0 labs/architecture-examples/javascriptmvc/jquery/buildAll.js
  5. +109 −0 labs/architecture-examples/javascriptmvc/jquery/class/class.html
  6. +785 −0 labs/architecture-examples/javascriptmvc/jquery/class/class.js
  7. +205 −0 labs/architecture-examples/javascriptmvc/jquery/class/class_test.js
  8. +15 −0 labs/architecture-examples/javascriptmvc/jquery/class/qunit.html
  9. +88 −0 labs/architecture-examples/javascriptmvc/jquery/controller/controller.html
  10. +1,089 −0 labs/architecture-examples/javascriptmvc/jquery/controller/controller.js
  11. +269 −0 labs/architecture-examples/javascriptmvc/jquery/controller/controller_test.js
  12. +54 −0 labs/architecture-examples/javascriptmvc/jquery/controller/demo-update.html
  13. +189 −0 labs/architecture-examples/javascriptmvc/jquery/controller/pages/listening.md
  14. +101 −0 labs/architecture-examples/javascriptmvc/jquery/controller/pages/plugin.md
  15. +21 −0 labs/architecture-examples/javascriptmvc/jquery/controller/qunit.html
  16. +18 −0 labs/architecture-examples/javascriptmvc/jquery/controller/route/qunit.html
  17. +35 −0 labs/architecture-examples/javascriptmvc/jquery/controller/route/route.html
  18. +31 −0 labs/architecture-examples/javascriptmvc/jquery/controller/route/route.js
  19. +10 −0 labs/architecture-examples/javascriptmvc/jquery/controller/route/route_test.js
  20. +21 −0 labs/architecture-examples/javascriptmvc/jquery/controller/subscribe/funcunit.html
  21. +56 −0 labs/architecture-examples/javascriptmvc/jquery/controller/subscribe/subscribe.html
  22. +54 −0 labs/architecture-examples/javascriptmvc/jquery/controller/subscribe/subscribe.js
  23. +21 −0 labs/architecture-examples/javascriptmvc/jquery/controller/view/qunit.html
  24. +50 −0 labs/architecture-examples/javascriptmvc/jquery/controller/view/test/qunit/controller_view_test.js
  25. +5 −0 labs/architecture-examples/javascriptmvc/jquery/controller/view/test/qunit/qunit.js
  26. +1 −0 labs/architecture-examples/javascriptmvc/jquery/controller/view/test/qunit/views/init.micro
  27. +121 −0 labs/architecture-examples/javascriptmvc/jquery/controller/view/view.js
  28. +48 −0 labs/architecture-examples/javascriptmvc/jquery/dom/closest/closest.js
  29. +90 −0 labs/architecture-examples/javascriptmvc/jquery/dom/compare/compare.html
  30. +85 −0 labs/architecture-examples/javascriptmvc/jquery/dom/compare/compare.js
  31. +24 −0 labs/architecture-examples/javascriptmvc/jquery/dom/compare/compare_test.js
  32. +20 −0 labs/architecture-examples/javascriptmvc/jquery/dom/compare/qunit.html
  33. +116 −0 labs/architecture-examples/javascriptmvc/jquery/dom/cookie/cookie.js
  34. +69 −0 labs/architecture-examples/javascriptmvc/jquery/dom/cur_styles/cur_styles.html
  35. +117 −0 labs/architecture-examples/javascriptmvc/jquery/dom/cur_styles/cur_styles.js
  36. +28 −0 labs/architecture-examples/javascriptmvc/jquery/dom/cur_styles/cur_styles_test.js
  37. +22 −0 labs/architecture-examples/javascriptmvc/jquery/dom/cur_styles/qunit.html
  38. +3 −0 labs/architecture-examples/javascriptmvc/jquery/dom/cur_styles/test/curStyles.micro
  39. +131 −0 labs/architecture-examples/javascriptmvc/jquery/dom/dimensions/dimensions.html
  40. +155 −0 labs/architecture-examples/javascriptmvc/jquery/dom/dimensions/dimensions.js
  41. +14 −0 labs/architecture-examples/javascriptmvc/jquery/dom/dimensions/dimensions_test.js
  42. +22 −0 labs/architecture-examples/javascriptmvc/jquery/dom/dimensions/qunit.html
  43. +3 −0 labs/architecture-examples/javascriptmvc/jquery/dom/dimensions/test/curStyles.micro
  44. 0 labs/architecture-examples/javascriptmvc/jquery/dom/dimensions/test/outer.micro
  45. +82 −0 labs/architecture-examples/javascriptmvc/jquery/dom/dom.js
  46. +144 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixture.html
  47. +903 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixture.js
  48. +332 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixture_test.js
  49. +1 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixtures/foo.json
  50. +3 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixtures/foobar.json
  51. +31 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixtures/messages.html
  52. +3 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixtures/remove.json
  53. +3 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/fixtures/test.json
  54. +22 −0 labs/architecture-examples/javascriptmvc/jquery/dom/fixture/qunit.html
  55. +56 −0 labs/architecture-examples/javascriptmvc/jquery/dom/form_params/form_params.html
  56. +164 −0 labs/architecture-examples/javascriptmvc/jquery/dom/form_params/form_params.js
  57. +69 −0 labs/architecture-examples/javascriptmvc/jquery/dom/form_params/form_params_test.js
  58. +22 −0 labs/architecture-examples/javascriptmvc/jquery/dom/form_params/qunit.html
  59. +30 −0 labs/architecture-examples/javascriptmvc/jquery/dom/form_params/test/basics.micro
  60. +20 −0 labs/architecture-examples/javascriptmvc/jquery/dom/form_params/test/checkbox.micro
  61. +7 −0 labs/architecture-examples/javascriptmvc/jquery/dom/form_params/test/truthy.micro
  62. +17 −0 labs/architecture-examples/javascriptmvc/jquery/dom/range/qunit.html
  63. +66 −0 labs/architecture-examples/javascriptmvc/jquery/dom/range/range.html
  64. +676 −0 labs/architecture-examples/javascriptmvc/jquery/dom/range/range.js
  65. +197 −0 labs/architecture-examples/javascriptmvc/jquery/dom/range/range_test.js
  66. +15 −0 labs/architecture-examples/javascriptmvc/jquery/dom/route/qunit.html
  67. +116 −0 labs/architecture-examples/javascriptmvc/jquery/dom/route/route.html
  68. +471 −0 labs/architecture-examples/javascriptmvc/jquery/dom/route/route.js
  69. +267 −0 labs/architecture-examples/javascriptmvc/jquery/dom/route/route_test.js
  70. +20 −0 labs/architecture-examples/javascriptmvc/jquery/dom/selection/qunit.html
  71. +56 −0 labs/architecture-examples/javascriptmvc/jquery/dom/selection/selection.html
  72. +242 −0 labs/architecture-examples/javascriptmvc/jquery/dom/selection/selection.js
  73. +39 −0 labs/architecture-examples/javascriptmvc/jquery/dom/selection/selection_test.js
  74. +84 −0 labs/architecture-examples/javascriptmvc/jquery/dom/within/within.js
  75. BIN labs/architecture-examples/javascriptmvc/jquery/download/btn.png
  76. +88 −0 labs/architecture-examples/javascriptmvc/jquery/download/download.css
  77. +369 −0 labs/architecture-examples/javascriptmvc/jquery/download/download.html
  78. +104 −0 labs/architecture-examples/javascriptmvc/jquery/download/download.js
  79. +15 −0 labs/architecture-examples/javascriptmvc/jquery/download/test/controllerpage.html
  80. +6,883 −0 labs/architecture-examples/javascriptmvc/jquery/download/test/jquery-1.4.3.js
  81. +16 −0 labs/architecture-examples/javascriptmvc/jquery/download/test/run.js
  82. +88 −0 labs/architecture-examples/javascriptmvc/jquery/event/default/default.html
  83. +156 −0 labs/architecture-examples/javascriptmvc/jquery/event/default/default.js
  84. +22 −0 labs/architecture-examples/javascriptmvc/jquery/event/default/default_pause_test.html
  85. +100 −0 labs/architecture-examples/javascriptmvc/jquery/event/default/default_pause_test.js
  86. +167 −0 labs/architecture-examples/javascriptmvc/jquery/event/default/default_test.js
  87. +117 −0 labs/architecture-examples/javascriptmvc/jquery/event/default/defaultjquery.html
  88. +22 −0 labs/architecture-examples/javascriptmvc/jquery/event/default/qunit.html
  89. +24 −0 labs/architecture-examples/javascriptmvc/jquery/event/destroyed/destroyed.html
  90. +40 −0 labs/architecture-examples/javascriptmvc/jquery/event/destroyed/destroyed.js
  91. +96 −0 labs/architecture-examples/javascriptmvc/jquery/event/destroyed/destroyed_menu.html
  92. +18 −0 labs/architecture-examples/javascriptmvc/jquery/event/destroyed/destroyed_test.js
  93. +21 −0 labs/architecture-examples/javascriptmvc/jquery/event/destroyed/qunit.html
  94. +131 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/drag.html
  95. +578 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/drag.js
  96. +237 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/drag_test.js
  97. +72 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/limit/limit.html
  98. +69 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/limit/limit.js
  99. +16 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/qunit.html
  100. +139 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/scroll/scroll.js
  101. +67 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/step/step.html
  102. +77 −0 labs/architecture-examples/javascriptmvc/jquery/event/drag/step/step.js
  103. +73 −0 labs/architecture-examples/javascriptmvc/jquery/event/drop/drop.html
  104. +426 −0 labs/architecture-examples/javascriptmvc/jquery/event/drop/drop.js
  105. +41 −0 labs/architecture-examples/javascriptmvc/jquery/event/drop/drop_test.js
  106. +42 −0 labs/architecture-examples/javascriptmvc/jquery/event/event.js
  107. +207 −0 labs/architecture-examples/javascriptmvc/jquery/event/handle/handle.js
  108. +268 −0 labs/architecture-examples/javascriptmvc/jquery/event/hashchange/hashchange.js
  109. +68 −0 labs/architecture-examples/javascriptmvc/jquery/event/hover/hover.html
  110. +251 −0 labs/architecture-examples/javascriptmvc/jquery/event/hover/hover.js
  111. +61 −0 labs/architecture-examples/javascriptmvc/jquery/event/hover/hover_test.js
  112. +16 −0 labs/architecture-examples/javascriptmvc/jquery/event/hover/qunit.html
  113. +32 −0 labs/architecture-examples/javascriptmvc/jquery/event/key/key.html
  114. +160 −0 labs/architecture-examples/javascriptmvc/jquery/event/key/key.js
  115. +26 −0 labs/architecture-examples/javascriptmvc/jquery/event/key/key_test.js
  116. +16 −0 labs/architecture-examples/javascriptmvc/jquery/event/key/qunit.html
  117. +173 −0 labs/architecture-examples/javascriptmvc/jquery/event/livehack/livehack.js
  118. +217 −0 labs/architecture-examples/javascriptmvc/jquery/event/pause/pause.html
  119. +169 −0 labs/architecture-examples/javascriptmvc/jquery/event/pause/pause.js
  120. +51 −0 labs/architecture-examples/javascriptmvc/jquery/event/pause/pause_test.js
  121. +20 −0 labs/architecture-examples/javascriptmvc/jquery/event/pause/qunit.html
  122. +146 −0 labs/architecture-examples/javascriptmvc/jquery/event/resize/demo.html
  123. +17 −0 labs/architecture-examples/javascriptmvc/jquery/event/resize/qunit.html
  124. +47 −0 labs/architecture-examples/javascriptmvc/jquery/event/resize/resize.html
  125. +159 −0 labs/architecture-examples/javascriptmvc/jquery/event/resize/resize.js
  126. +69 −0 labs/architecture-examples/javascriptmvc/jquery/event/resize/resize_test.js
  127. +20 −0 labs/architecture-examples/javascriptmvc/jquery/event/selection/qunit.html
  128. +101 −0 labs/architecture-examples/javascriptmvc/jquery/event/selection/selection.html
  129. +96 −0 labs/architecture-examples/javascriptmvc/jquery/event/selection/selection.js
  130. +39 −0 labs/architecture-examples/javascriptmvc/jquery/event/selection/selection_test.js
  131. +20 −0 labs/architecture-examples/javascriptmvc/jquery/event/swipe/qunit.html
  132. +50 −0 labs/architecture-examples/javascriptmvc/jquery/event/swipe/swipe.html
  133. +103 −0 labs/architecture-examples/javascriptmvc/jquery/event/swipe/swipe.js
  134. +110 −0 labs/architecture-examples/javascriptmvc/jquery/event/swipe/swipe_test.js
  135. +33 −0 labs/architecture-examples/javascriptmvc/jquery/event/tap/tap.html
  136. +51 −0 labs/architecture-examples/javascriptmvc/jquery/event/tap/tap.js
  137. +23 −0 labs/architecture-examples/javascriptmvc/jquery/generate/app
  138. +35 −0 labs/architecture-examples/javascriptmvc/jquery/generate/coffee/controller
  139. +11 −0 ...ecture-examples/javascriptmvc/jquery/generate/coffee/templates/controller/(underscore).coffee.ejs
  140. +24 −0 ...itecture-examples/javascriptmvc/jquery/generate/coffee/templates/controller/(underscore).html.ejs
  141. +7 −0 ...e-examples/javascriptmvc/jquery/generate/coffee/templates/controller/(underscore)_test.coffee.ejs
  142. +16 −0 ...architecture-examples/javascriptmvc/jquery/generate/coffee/templates/controller/funcunit.html.ejs
  143. +36 −0 labs/architecture-examples/javascriptmvc/jquery/generate/controller
  144. +74 −0 labs/architecture-examples/javascriptmvc/jquery/generate/model
  145. +21 −0 labs/architecture-examples/javascriptmvc/jquery/generate/page
  146. +20 −0 labs/architecture-examples/javascriptmvc/jquery/generate/plugin
  147. +74 −0 labs/architecture-examples/javascriptmvc/jquery/generate/scaffold
  148. +29 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/(application_name).css.ejs
  149. +28 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/(application_name).html.ejs
  150. +7 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/(application_name).js.ejs
  151. +3 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/(application_name).md.ejs
  152. 0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/docs/.ignore
  153. 0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/fixtures/.ignore
  154. +5 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/fixtures/fixtures.js.ejs
  155. +15 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/funcunit.html.ejs
  156. 0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/models/.ignore
  157. +2 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/models/models.js.ejs
  158. +21 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/qunit.html.ejs
  159. +21 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/scripts/build.html.ejs
  160. +6 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/scripts/build.js.ejs
  161. +17 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/scripts/clean.js.ejs
  162. +7 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/scripts/crawl.js.ejs
  163. +8 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/scripts/docs.js.ejs
  164. +11 −0 ...examples/javascriptmvc/jquery/generate/templates/app/test/funcunit/(application_name)_test.js.ejs
  165. +2 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/test/funcunit/funcunit.js.ejs
  166. +7 −0 ...re-examples/javascriptmvc/jquery/generate/templates/app/test/qunit/(application_name)_test.js.ejs
  167. +1 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/app/test/qunit/qunit.js.ejs
  168. +25 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/controller/(underscore).html.ejs
  169. +21 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/controller/(underscore).js.ejs
  170. +14 −0 ...architecture-examples/javascriptmvc/jquery/generate/templates/controller/(underscore)_test.js.ejs
  171. +16 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/controller/funcunit.html.ejs
  172. 0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/controller/views/.ignore
  173. +1 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/controller/views/init.ejs.ejs
  174. +7 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/fixturemake.ejs
  175. +75 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/model.js
  176. +21 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/model/models/(underscore).js.ejs
  177. +51 −0 ...ecture-examples/javascriptmvc/jquery/generate/templates/model/test/qunit/(underscore)_test.js.ejs
  178. +22 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/page.ejs
  179. +24 −0 .../architecture-examples/javascriptmvc/jquery/generate/templates/plugin/(application_name).html.ejs
  180. +3 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/plugin/(application_name).js.ejs
  181. +10 −0 ...chitecture-examples/javascriptmvc/jquery/generate/templates/plugin/(application_name)_test.js.ejs
  182. +18 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/plugin/qunit.html.ejs
  183. +29 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/create/create.html.ejs
  184. +31 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/create/create.js.ejs
  185. +22 −0 .../architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/create/create_test.js.ejs
  186. +15 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/create/funcunit.html.ejs
  187. +9 −0 .../architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/create/views/init.ejs.ejs
  188. +15 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/list/funcunit.html.ejs
  189. +31 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/list/list.html.ejs
  190. +42 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/list/list.js.ejs
  191. +26 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/list/list_test.js.ejs
  192. +2 −0 ...tecture-examples/javascriptmvc/jquery/generate/templates/scaffold/list/views/(underscore).ejs.ejs
  193. +5 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffold/list/views/init.ejs.ejs
  194. +2 −0 labs/architecture-examples/javascriptmvc/jquery/generate/templates/scaffoldHookup.ejs
  195. +60 −0 labs/architecture-examples/javascriptmvc/jquery/generate/test/app_plugin_model_controller.js
  196. +3 −0 labs/architecture-examples/javascriptmvc/jquery/generate/test/run.js
  197. +87 −0 labs/architecture-examples/javascriptmvc/jquery/generate/test/scaffold.js
  198. +9,266 −0 labs/architecture-examples/javascriptmvc/jquery/jquery.js
  199. +346 −0 labs/architecture-examples/javascriptmvc/jquery/jquerymx.md
  200. +212 −0 labs/architecture-examples/javascriptmvc/jquery/lang/json/json.js
  201. +1 −0 labs/architecture-examples/javascriptmvc/jquery/lang/lang_test.js
  202. +25 −0 labs/architecture-examples/javascriptmvc/jquery/lang/object/object.html
  203. +225 −0 labs/architecture-examples/javascriptmvc/jquery/lang/object/object.js
  204. +105 −0 labs/architecture-examples/javascriptmvc/jquery/lang/object/object_test.js
  205. +17 −0 labs/architecture-examples/javascriptmvc/jquery/lang/object/qunit.html
  206. +315 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/delegate/delegate.js
  207. +224 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/delegate/delegate_test.js
  208. +140 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/demo.html
  209. +83 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/observe.html
  210. +1,021 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/observe.js
  211. +86 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/observe.md
  212. +312 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/observe_test.js
  213. +17 −0 labs/architecture-examples/javascriptmvc/jquery/lang/observe/qunit.html
  214. +24 −0 labs/architecture-examples/javascriptmvc/jquery/lang/openajax/openajax.html
  215. +198 −0 labs/architecture-examples/javascriptmvc/jquery/lang/openajax/openajax.js
  216. +17 −0 labs/architecture-examples/javascriptmvc/jquery/lang/qunit.html
Sorry, we could not display the entire diff because too many files (596) changed.
View
2 index.html
@@ -85,7 +85,7 @@
<a href="labs/architecture-examples/montage/" data-source="https://github.com/Motorola-Mobility/montage" data-content="Montage simplifies the development of rich HTML5 applications by providing modular components, real-time two-way data binding, CommonJS dependency management, and many more conveniences.">Montage</a>
</li>
<li class="labs">
- <a href="https://github.com/addyosmani/todomvc/tree/gh-pages/labs/architecture-examples/canjs#canjs-and-javascriptmvc" data-source="http://javascriptmvc.com" data-content="JavaScriptMVC is an open-source framework containing the best ideas in jQuery development. It guides you to successfully completed projects by promoting best practices, maintainability, and convention over configuration.">JavaScriptMVC</a>
+ <a href="labs/architecture-examples/javascriptmvc/todo" data-source="http://javascriptmvc.com" data-content="JavaScriptMVC is an open-source framework containing the best ideas in jQuery development. It guides you to successfully completed projects by promoting best practices, maintainability, and convention over configuration.">JavaScriptMVC</a>
</li>
<li class="labs">
<a href="labs/architecture-examples/extjs/" data-source="http://www.sencha.com/products/extjs" data-content="Ext JS 4 is the next major advancement in our JavaScript framework. Featuring expanded functionality, plugin-free charting, and a new MVC architecture it's the best Ext JS yet. Create incredible web apps for every browser.">Ext.js</a>
View
24 labs/architecture-examples/javascriptmvc/jquery/README
@@ -0,0 +1,24 @@
+TOC:
+ A. How to get (and contribute) to JMVC
+
+
+A. How to get (and contribute) JMVC
+
+ 1. Start a new project in git.
+
+ 2. Fork ....
+ http://github.com/jupiterjs/steal and
+ http://github.com/jupiterjs/jquerymx
+
+ 3. Add steal and jquerymx as submodules of your project...
+ git submodule add git@github.com:_YOU_/steal.git steal
+ git submodule add git@github.com:_YOU_/jquerymx.git jquery
+
+ * Notice jquerymx is under the jquery folder
+
+ 4. Learn a little more about submodules ...
+ http://johnleach.co.uk/words/archives/2008/10/12/323/git-submodules-in-n-easy-steps
+
+ 5. Make changes in steal or jquerymx, and push them back to your fork.
+
+ 6. Make a pull request to your fork.
View
146 labs/architecture-examples/javascriptmvc/jquery/build.js
@@ -0,0 +1,146 @@
+// load('jquery/build.js')
+
+load('steal/rhino/rhino.js')
+
+var i, fileName, cmd,
+ plugins = [
+ "class" ,
+ "controller",
+ {
+ plugin: "controller/subscribe",
+ exclude: ["jquery/controller/controller.js",
+ "jquery/class/class.js",
+ "jquery/lang/lang.js",
+ "jquery/event/destroyed/destroyed.js",
+ "jquery/controller/controller.js"]},
+ "event/default",
+ "event/destroyed",
+ "event/drag",
+ "event/pause",
+ "event/resize",
+ {
+ plugin: "event/drag/limit",
+ exclude: ["jquery/lang/vector/vector.js", "jquery/event/livehack/livehack.js", "jquery/event/drag/drag.js"]},
+ {
+ plugin: "event/drag/scroll",
+ exclude: ["jquery/dom/within/within.js", "jquery/dom/compare/compare.js", "jquery/event/drop/drop.js","jquery/lang/vector/vector.js", "jquery/event/livehack/livehack.js", "jquery/event/drag/drag.js"]},
+ {
+ plugin: "event/drop",
+ exclude: ["jquery/lang/vector/vector.js", "jquery/event/livehack/livehack.js", "jquery/event/drag/drag.js"]},
+ "event/hover",
+ "view/ejs",
+ "dom/closest",
+ "dom/compare",
+ {
+ plugin: "dom/dimensions",
+ fileName: "jquery.dimensions.etc.js"
+ },
+ "dom/fixture",
+ "dom/form_params",
+ "dom/within",
+ "dom/cur_styles",
+ "model",
+ {
+ plugin: "model/backup",
+ exclude: ["jquery/class/class.js",
+ "jquery/lang/lang.js",
+ "jquery/event/destroyed/destroyed.js",
+ "jquery/lang/openajax/openajax.js",
+ "jquery/model/model.js"]
+ },
+ {
+ plugin: "model/list",
+ exclude: ["jquery/class/class.js",
+ "jquery/lang/lang.js",
+ "jquery/event/destroyed/destroyed.js",
+ "jquery/lang/openajax/openajax.js",
+ "jquery/model/model.js"]
+ },
+ {
+ plugin: "model/list/cookie",
+ exclude: ["jquery/class/class.js",
+ "jquery/lang/lang.js",
+ "jquery/event/destroyed/destroyed.js",
+ "jquery/lang/openajax/openajax.js",
+ "jquery/model/model.js",
+ "jquery/model/list/list.js"]
+ },
+ {
+ plugin: "model/list/local",
+ exclude: ["jquery/class/class.js",
+ "jquery/lang/lang.js",
+ "jquery/event/destroyed/destroyed.js",
+ "jquery/lang/openajax/openajax.js",
+ "jquery/model/model.js",
+ "jquery/model/list/list.js"]
+ },
+ {
+ plugin: "model/validations",
+ exclude: ["jquery/class/class.js",
+ "jquery/lang/lang.js",
+ "jquery/event/destroyed/destroyed.js",
+ "jquery/lang/openajax/openajax.js",
+ "jquery/model/model.js"]
+ },
+ "view",
+ "view/ejs",
+ "view/jaml",
+ "view/micro",
+ "view/tmpl"
+]
+
+
+steal.File('jquery/dist').mkdir();
+steal('steal/build/pluginify').then( function(s){
+var plugin, exclude, fileDest, fileName;
+ for(i=0; i<plugins.length; i++){
+ plugin = plugins[i];
+ exclude = [];
+ fileName = null;
+ if (typeof plugin != "string") {
+ fileName = plugin.fileName;
+ exclude = plugin.exclude || [];
+ plugin = plugin.plugin;
+ }
+ fileName = fileName || "jquery."+plugin.replace(/\//g, ".").replace(/dom\./, "").replace(/\_/, "")+".js";
+ fileDest = "jquery/dist/"+fileName
+ s.build.pluginify("jquery/"+plugin,{
+ nojquery: true,
+ out: fileDest,
+ exclude: exclude.length? exclude: false
+ })
+
+
+ var outBaos = new java.io.ByteArrayOutputStream();
+ var output = new java.io.PrintStream(outBaos);
+ runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--js", fileDest, {
+ output: output
+ });
+
+ var minFileDest = fileDest.replace(".js", ".min.js")
+ new steal.File(minFileDest).save(outBaos.toString());
+ }
+})
+/*
+for (i = 0; i < plugins.length; i++) {
+ plugin = plugins[i];
+ exclude = [];
+ fileName = null;
+ if (typeof plugin != "string") {
+ fileName = plugin.fileName;
+ exclude = plugin.exclude || [];
+ plugin = plugin.plugin;
+ }
+ fileName = fileName || "jquery." + plugin.replace(/\//g, ".").replace(/dom\./, "").replace(/\_/, "") + ".js";
+ fileDest = "jquery/dist/" + fileName
+ // compress
+ var outBaos = new java.io.ByteArrayOutputStream();
+ var output = new java.io.PrintStream(outBaos);
+ runCommand("java", "-jar", "steal/build/scripts/compiler.jar", "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--warning_level", "QUIET", "--js", fileDest, {
+ output: output
+ });
+
+ var minFileDest = fileDest.replace(".js", ".min.js")
+ new steal.File(minFileDest).save(outBaos.toString());
+ print("***" + fileName + " pluginified and compressed")
+}*/
View
130 labs/architecture-examples/javascriptmvc/jquery/buildAll.js
@@ -0,0 +1,130 @@
+// load('jquery/buildAll.js')
+
+load('steal/rhino/rhino.js')
+
+
+// load every plugin in a single app
+// get dependency graph
+// generate single script
+
+steal('steal/build/pluginify','steal/build/apps','steal/build/scripts').then( function(s){
+ var ignore = /\.\w+|test|generate|dist|qunit|fixtures|pages/
+
+ var plugins = [],
+ /**
+ * {"path/to/file.js" : ["file2/thing.js", ...]}
+ */
+ files = {};
+
+ s.File('jquery').contents(function( name, type, current ) {
+ if (type !== 'file' && !ignore.test(name)) {
+ var folder = current+"/"+name;
+ if(readFile(folder+"/"+name+".js")){
+ print(folder);
+ plugins.push(folder);
+ steal.File(folder).contents(arguments.callee, folder)
+ }
+
+ //steal.File(path + "/" + (current ? current + "/" : "") + name).contents(arguments.callee, (current ? current + "/" : "") + name);
+ }
+ },"jquery");
+
+ // tell it to load all plugins into this page
+
+
+ //steal.win().build_in_progress = true;
+ print(" LOADING APP ")
+ steal.build.open('steal/rhino/blank.html', {
+ startFiles: plugins
+ }, function(opener){
+
+ opener.each('js', function(options, text, stl){
+ print(options.rootSrc)
+ var dependencies = files[options.rootSrc] = [];
+ if(stl.dependencies){
+ for (var d = 0; d < stl.dependencies.length; d++) {
+ var depend = stl.dependencies[d];
+ if (depend.options.rootSrc !== "jquery/jquery.js") {
+ dependencies.push(depend.options.rootSrc);
+ }
+ }
+ }
+ })
+
+ s.File("jquery/dist/standalone").mkdirs();
+ s.File("jquery/dist/standalone/dependencies.json").save($.toJSON(files));
+ //get each file ...
+ print("Creating jquery/dist/standalone/")
+ var compressor = s.build.builders.scripts.compressors[ "localClosure"]()
+ for(var path in files){
+ if(path == "jquery/jquery.js"){
+ continue;
+ }
+ var content = readFile(path);
+ var funcContent = s.build.pluginify.getFunction(content);
+ if(typeof funcContent == "undefined"){
+ content = "";
+ } else {
+ content = "("+s.build.pluginify.getFunction(content)+")(jQuery);";
+ }
+ var out = path.replace(/\/\w+\.js/,"").replace(/\//g,".");
+ content = s.build.builders.scripts.clean(content);
+ print(" "+out+"");
+ content = s.build.builders.scripts.clean(content);
+ s.File("jquery/dist/standalone/"+out+".js").save(content);
+ s.File("jquery/dist/standalone/"+out+".min.js").save(compressor(content));
+ }
+
+ })
+
+ /*
+ var pageSteal = steal.build.open("steal/rhino/empty.html").steal,
+ steals = pageSteal.total,
+
+ files = {},
+ depends = function(stl, steals){
+ if(stl.dependencies){
+ for (var d = 0; d < stl.dependencies.length; d++) {
+ var depend = stl.dependencies[d];
+ if(!steals[depend.path]){
+ steals[depend.path] = true;
+ print("123 " + depend.path);
+ //depends(depend, steals);
+ }
+
+
+ }
+ }
+ },
+ all = function(c){
+ for(var i =0; i < steals.length; i++){
+ var pSteal =steals[i];
+
+ if(!pSteal.func){
+ c(pSteal)
+ }
+
+ }
+
+ };
+ print(" LOADED, GETTING DEPENDS");
+ all(function(stl){
+ files[stl.path] = stl;
+ })
+ all(function(stl){
+ print(stl.path)
+ var dependencies = files[stl.path] = [];
+ if(stl.dependencies){
+ for (var d = 0; d < stl.dependencies.length; d++) {
+ var depend = stl.dependencies[d];
+ if (depend.path !== "jquery/jquery.js") {
+ dependencies.push(depend.path);
+ }
+ }
+ }
+ })*/
+
+
+
+
+})
View
109 labs/architecture-examples/javascriptmvc/jquery/class/class.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+ <head>
+ <title>jQuery.Class Demo</title>
+ <style type='text/css'>
+ body {font-family: verdana}
+ .tabs, .history_tabs {
+
+ padding: 0px; margin: 20px 0 0 0;
+ }
+ li {
+ float: left;
+ padding: 10px;
+ background-color: #F6F6F6;
+ list-style: none;
+ margin-left: 10px;
+ }
+ li a {
+ color: #1C94C4;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ li.active a {
+ color: #F6A828;
+ cursor: default;
+ }
+ .tab {
+ border: solid 1px #F6A828;
+ }
+ /* clearfix from jQueryUI */
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+ .ui-helper-clearfix { display: inline-block; }
+ /* required comment for clearfix to work in Opera \*/
+ * html .ui-helper-clearfix { height:1%; }
+ .ui-helper-clearfix { display:block; }
+ /* end clearfix */
+ </style>
+ </head>
+ <body>
+<p>jQuery.Class Demo shows a tabs controller extended to work with history.</p>
+<div id="demo-html">
+<h2>Basic Tabs</h2>
+<ul id='tabs1' class='ui-helper-clearfix''>
+ <li><a href='#tab1'>Tab 1</a></li>
+ <li><a href='#tab2'>Tab 2</a></li>
+ <li><a href='#tab3'>Tab 3</a></li>
+</ul>
+<div id='tab1' class='tab'>Tab 1 Content</div>
+<div id='tab2' class='tab'>Tab 2 Content</div>
+<div id='tab3' class='tab'>Tab 3 Content</div>
+<h2>History Tabs</h2>
+<ul id='tabs2' class='ui-helper-clearfix''>
+ <li><a href='#tab4'>Tab 4</a></li>
+ <li><a href='#tab5'>Tab 5</a></li>
+ <li><a href='#tab6'>Tab 6</a></li>
+</ul>
+<div id='tab4' class='tab'>Tab 4 Content</div>
+<div id='tab5' class='tab'>Tab 5 Content</div>
+<div id='tab6' class='tab'>Tab 6 Content</div>
+</div>
+<script type='text/javascript'>DEMO_HTML = document.getElementById('demo-html').innerHTML</script>
+<script type='text/javascript' src='../../steal/steal.js'></script>
+<script type='text/javascript' id="demo-source">
+steal('jquery/controller').then(function(){
+$.Controller("Tabs",{
+ init : function(){
+ this.element.children("li:first").addClass('active')
+ var tab = this.tab;
+ this.element.children("li:gt(0)").each(function(){
+ tab($(this)).hide()
+ })
+ },
+ tab : function(li){
+ return $(li.find("a").attr("href"))
+ },
+ "li click" : function(el, ev){
+ ev.preventDefault();
+ this.activate(el)
+ },
+ activate : function(el){
+ this.tab(this.find('.active').removeClass('active')).hide()
+ this.tab(el.addClass('active')).show();
+ }
+})
+
+//inherit from tabs
+Tabs("HistoryTabs",{
+
+ // ignore clicks
+ "li click" : function(){},
+
+ // listen for history changes
+ "{window} hashchange" : function(ev){
+ var hash = window.location.hash;
+ this.activate(hash === '' || hash === '#' ?
+ this.element.find("li:first") :
+ this.element.find("a[href="+hash+"]").parent()
+ )
+ }
+})
+
+//adds the controller to the element
+$("#tabs1").tabs();
+$("#tabs2").history_tabs();
+})
+</script>
+ </body>
+</html>
View
785 labs/architecture-examples/javascriptmvc/jquery/class/class.js
@@ -0,0 +1,785 @@
+//jQuery.Class
+// This is a modified version of John Resig's class
+// http://ejohn.org/blog/simple-javascript-inheritance/
+// It provides class level inheritance and callbacks.
+//!steal-clean
+steal("jquery","jquery/lang/string",function( $ ) {
+
+ // =============== HELPERS =================
+
+ // if we are initializing a new class
+ var initializing = false,
+ makeArray = $.makeArray,
+ isFunction = $.isFunction,
+ isArray = $.isArray,
+ extend = $.extend,
+ getObject = $.String.getObject,
+ concatArgs = function(arr, args){
+ return arr.concat(makeArray(args));
+ },
+
+ // tests if we can get super in .toString()
+ fnTest = /xyz/.test(function() {
+ xyz;
+ }) ? /\b_super\b/ : /.*/,
+
+ // overwrites an object with methods, sets up _super
+ // newProps - new properties
+ // oldProps - where the old properties might be
+ // addTo - what we are adding to
+ inheritProps = function( newProps, oldProps, addTo ) {
+ addTo = addTo || newProps
+ for ( var name in newProps ) {
+ // Check if we're overwriting an existing function
+ addTo[name] = isFunction(newProps[name]) &&
+ isFunction(oldProps[name]) &&
+ fnTest.test(newProps[name]) ? (function( name, fn ) {
+ return function() {
+ var tmp = this._super,
+ ret;
+
+ // Add a new ._super() method that is the same method
+ // but on the super-class
+ this._super = oldProps[name];
+
+ // The method only need to be bound temporarily, so we
+ // remove it when we're done executing
+ ret = fn.apply(this, arguments);
+ this._super = tmp;
+ return ret;
+ };
+ })(name, newProps[name]) : newProps[name];
+ }
+ },
+ STR_PROTOTYPE = 'prototype'
+
+ /**
+ * @class jQuery.Class
+ * @plugin jquery/class
+ * @parent jquerymx
+ * @download dist/jquery/jquery.class.js
+ * @test jquery/class/qunit.html
+ * @description Easy inheritance in JavaScript.
+ *
+ * Class provides simulated inheritance in JavaScript. Use clss to bridge the gap between
+ * jQuery's functional programming style and Object Oriented Programming. It
+ * is based off John Resig's [http://ejohn.org/blog/simple-javascript-inheritance/|Simple Class]
+ * Inheritance library. Besides prototypal inheritance, it includes a few important features:
+ *
+ * - Static inheritance
+ * - Introspection
+ * - Namespaces
+ * - Setup and initialization methods
+ * - Easy callback function creation
+ *
+ *
+ * The [mvc.class Get Started with jQueryMX] has a good walkthrough of $.Class.
+ *
+ * ## Static v. Prototype
+ *
+ * Before learning about Class, it's important to
+ * understand the difference between
+ * a class's __static__ and __prototype__ properties.
+ *
+ * //STATIC
+ * MyClass.staticProperty //shared property
+ *
+ * //PROTOTYPE
+ * myclass = new MyClass()
+ * myclass.prototypeMethod() //instance method
+ *
+ * A static (or class) property is on the Class constructor
+ * function itself
+ * and can be thought of being shared by all instances of the
+ * Class. Prototype propertes are available only on instances of the Class.
+ *
+ * ## A Basic Class
+ *
+ * The following creates a Monster class with a
+ * name (for introspection), static, and prototype members.
+ * Every time a monster instance is created, the static
+ * count is incremented.
+ *
+ * @codestart
+ * $.Class('Monster',
+ * /* @static *|
+ * {
+ * count: 0
+ * },
+ * /* @prototype *|
+ * {
+ * init: function( name ) {
+ *
+ * // saves name on the monster instance
+ * this.name = name;
+ *
+ * // sets the health
+ * this.health = 10;
+ *
+ * // increments count
+ * this.constructor.count++;
+ * },
+ * eat: function( smallChildren ){
+ * this.health += smallChildren;
+ * },
+ * fight: function() {
+ * this.health -= 2;
+ * }
+ * });
+ *
+ * hydra = new Monster('hydra');
+ *
+ * dragon = new Monster('dragon');
+ *
+ * hydra.name // -> hydra
+ * Monster.count // -> 2
+ * Monster.shortName // -> 'Monster'
+ *
+ * hydra.eat(2); // health = 12
+ *
+ * dragon.fight(); // health = 8
+ *
+ * @codeend
+ *
+ *
+ * Notice that the prototype <b>init</b> function is called when a new instance of Monster is created.
+ *
+ *
+ * ## Inheritance
+ *
+ * When a class is extended, all static and prototype properties are available on the new class.
+ * If you overwrite a function, you can call the base class's function by calling
+ * <code>this._super</code>. Lets create a SeaMonster class. SeaMonsters are less
+ * efficient at eating small children, but more powerful fighters.
+ *
+ *
+ * Monster("SeaMonster",{
+ * eat: function( smallChildren ) {
+ * this._super(smallChildren / 2);
+ * },
+ * fight: function() {
+ * this.health -= 1;
+ * }
+ * });
+ *
+ * lockNess = new SeaMonster('Lock Ness');
+ * lockNess.eat(4); //health = 12
+ * lockNess.fight(); //health = 11
+ *
+ * ### Static property inheritance
+ *
+ * You can also inherit static properties in the same way:
+ *
+ * $.Class("First",
+ * {
+ * staticMethod: function() { return 1;}
+ * },{})
+ *
+ * First("Second",{
+ * staticMethod: function() { return this._super()+1;}
+ * },{})
+ *
+ * Second.staticMethod() // -> 2
+ *
+ * ## Namespaces
+ *
+ * Namespaces are a good idea! We encourage you to namespace all of your code.
+ * It makes it possible to drop your code into another app without problems.
+ * Making a namespaced class is easy:
+ *
+ *
+ * $.Class("MyNamespace.MyClass",{},{});
+ *
+ * new MyNamespace.MyClass()
+ *
+ *
+ * <h2 id='introspection'>Introspection</h2>
+ *
+ * Often, it's nice to create classes whose name helps determine functionality. Ruby on
+ * Rails's [http://api.rubyonrails.org/classes/ActiveRecord/Base.html|ActiveRecord] ORM class
+ * is a great example of this. Unfortunately, JavaScript doesn't have a way of determining
+ * an object's name, so the developer must provide a name. Class fixes this by taking a String name for the class.
+ *
+ * $.Class("MyOrg.MyClass",{},{})
+ * MyOrg.MyClass.shortName //-> 'MyClass'
+ * MyOrg.MyClass.fullName //-> 'MyOrg.MyClass'
+ *
+ * The fullName (with namespaces) and the shortName (without namespaces) are added to the Class's
+ * static properties.
+ *
+ *
+ * ## Setup and initialization methods
+ *
+ * <p>
+ * Class provides static and prototype initialization functions.
+ * These come in two flavors - setup and init.
+ * Setup is called before init and
+ * can be used to 'normalize' init's arguments.
+ * </p>
+ * <div class='whisper'>PRO TIP: Typically, you don't need setup methods in your classes. Use Init instead.
+ * Reserve setup methods for when you need to do complex pre-processing of your class before init is called.
+ *
+ * </div>
+ * @codestart
+ * $.Class("MyClass",
+ * {
+ * setup: function() {} //static setup
+ * init: function() {} //static constructor
+ * },
+ * {
+ * setup: function() {} //prototype setup
+ * init: function() {} //prototype constructor
+ * })
+ * @codeend
+ *
+ * ### Setup
+ *
+ * Setup functions are called before init functions. Static setup functions are passed
+ * the base class followed by arguments passed to the extend function.
+ * Prototype static functions are passed the Class constructor
+ * function arguments.
+ *
+ * If a setup function returns an array, that array will be used as the arguments
+ * for the following init method. This provides setup functions the ability to normalize
+ * arguments passed to the init constructors. They are also excellent places
+ * to put setup code you want to almost always run.
+ *
+ *
+ * The following is similar to how [jQuery.Controller.prototype.setup]
+ * makes sure init is always called with a jQuery element and merged options
+ * even if it is passed a raw
+ * HTMLElement and no second parameter.
+ *
+ * $.Class("jQuery.Controller",{
+ * ...
+ * },{
+ * setup: function( el, options ) {
+ * ...
+ * return [$(el),
+ * $.extend(true,
+ * this.Class.defaults,
+ * options || {} ) ]
+ * }
+ * })
+ *
+ * Typically, you won't need to make or overwrite setup functions.
+ *
+ * ### Init
+ *
+ * Init functions are called after setup functions.
+ * Typically, they receive the same arguments
+ * as their preceding setup function. The Foo class's <code>init</code> method
+ * gets called in the following example:
+ *
+ * $.Class("Foo", {
+ * init: function( arg1, arg2, arg3 ) {
+ * this.sum = arg1+arg2+arg3;
+ * }
+ * })
+ * var foo = new Foo(1,2,3);
+ * foo.sum //-> 6
+ *
+ * ## Proxies
+ *
+ * Similar to jQuery's proxy method, Class provides a
+ * [jQuery.Class.static.proxy proxy]
+ * function that returns a callback to a method that will always
+ * have
+ * <code>this</code> set to the class or instance of the class.
+ *
+ *
+ * The following example uses this.proxy to make sure
+ * <code>this.name</code> is available in <code>show</code>.
+ *
+ * $.Class("Todo",{
+ * init: function( name ) {
+ * this.name = name
+ * },
+ * get: function() {
+ * $.get("/stuff",this.proxy('show'))
+ * },
+ * show: function( txt ) {
+ * alert(this.name+txt)
+ * }
+ * })
+ * new Todo("Trash").get()
+ *
+ * Callback is available as a static and prototype method.
+ *
+ * ## Demo
+ *
+ * @demo jquery/class/class.html
+ *
+ *
+ * @constructor
+ *
+ * To create a Class call:
+ *
+ * $.Class( [NAME , STATIC,] PROTOTYPE ) -> Class
+ *
+ * <div class='params'>
+ * <div class='param'><label>NAME</label><code>{optional:String}</code>
+ * <p>If provided, this sets the shortName and fullName of the
+ * class and adds it and any necessary namespaces to the
+ * window object.</p>
+ * </div>
+ * <div class='param'><label>STATIC</label><code>{optional:Object}</code>
+ * <p>If provided, this creates static properties and methods
+ * on the class.</p>
+ * </div>
+ * <div class='param'><label>PROTOTYPE</label><code>{Object}</code>
+ * <p>Creates prototype methods on the class.</p>
+ * </div>
+ * </div>
+ *
+ * When a Class is created, the static [jQuery.Class.static.setup setup]
+ * and [jQuery.Class.static.init init] methods are called.
+ *
+ * To create an instance of a Class, call:
+ *
+ * new Class([args ... ]) -> instance
+ *
+ * The created instance will have all the
+ * prototype properties and methods defined by the PROTOTYPE object.
+ *
+ * When an instance is created, the prototype [jQuery.Class.prototype.setup setup]
+ * and [jQuery.Class.prototype.init init] methods
+ * are called.
+ */
+
+ clss = $.Class = function() {
+ if (arguments.length) {
+ clss.extend.apply(clss, arguments);
+ }
+ };
+
+ /* @Static*/
+ extend(clss, {
+ /**
+ * @function proxy
+ * Returns a callback function for a function on this Class.
+ * Proxy ensures that 'this' is set appropriately.
+ * @codestart
+ * $.Class("MyClass",{
+ * getData: function() {
+ * this.showing = null;
+ * $.get("data.json",this.proxy('gotData'),'json')
+ * },
+ * gotData: function( data ) {
+ * this.showing = data;
+ * }
+ * },{});
+ * MyClass.showData();
+ * @codeend
+ * <h2>Currying Arguments</h2>
+ * Additional arguments to proxy will fill in arguments on the returning function.
+ * @codestart
+ * $.Class("MyClass",{
+ * getData: function( <b>callback</b> ) {
+ * $.get("data.json",this.proxy('process',<b>callback</b>),'json');
+ * },
+ * process: function( <b>callback</b>, jsonData ) { //callback is added as first argument
+ * jsonData.processed = true;
+ * callback(jsonData);
+ * }
+ * },{});
+ * MyClass.getData(showDataFunc)
+ * @codeend
+ * <h2>Nesting Functions</h2>
+ * Proxy can take an array of functions to call as
+ * the first argument. When the returned callback function
+ * is called each function in the array is passed the return value of the prior function. This is often used
+ * to eliminate currying initial arguments.
+ * @codestart
+ * $.Class("MyClass",{
+ * getData: function( callback ) {
+ * //calls process, then callback with value from process
+ * $.get("data.json",this.proxy(['process2',callback]),'json')
+ * },
+ * process2: function( type,jsonData ) {
+ * jsonData.processed = true;
+ * return [jsonData];
+ * }
+ * },{});
+ * MyClass.getData(showDataFunc);
+ * @codeend
+ * @param {String|Array} fname If a string, it represents the function to be called.
+ * If it is an array, it will call each function in order and pass the return value of the prior function to the
+ * next function.
+ * @return {Function} the callback function.
+ */
+ proxy: function( funcs ) {
+
+ //args that should be curried
+ var args = makeArray(arguments),
+ self;
+
+ // get the functions to callback
+ funcs = args.shift();
+
+ // if there is only one function, make funcs into an array
+ if (!isArray(funcs) ) {
+ funcs = [funcs];
+ }
+
+ // keep a reference to us in self
+ self = this;
+
+ //!steal-remove-start
+ for( var i =0; i< funcs.length;i++ ) {
+ if(typeof funcs[i] == "string" && !isFunction(this[funcs[i]])){
+ throw ("class.js "+( this.fullName || this.Class.fullName)+" does not have a "+funcs[i]+"method!");
+ }
+ }
+ //!steal-remove-end
+ return function class_cb() {
+ // add the arguments after the curried args
+ var cur = concatArgs(args, arguments),
+ isString,
+ length = funcs.length,
+ f = 0,
+ func;
+
+ // go through each function to call back
+ for (; f < length; f++ ) {
+ func = funcs[f];
+ if (!func ) {
+ continue;
+ }
+
+ // set called with the name of the function on self (this is how this.view works)
+ isString = typeof func == "string";
+ if ( isString && self._set_called ) {
+ self.called = func;
+ }
+
+ // call the function
+ cur = (isString ? self[func] : func).apply(self, cur || []);
+
+ // pass the result to the next function (if there is a next function)
+ if ( f < length - 1 ) {
+ cur = !isArray(cur) || cur._use_call ? [cur] : cur
+ }
+ }
+ return cur;
+ }
+ },
+ /**
+ * @function newInstance
+ * Creates a new instance of the class. This method is useful for creating new instances
+ * with arbitrary parameters.
+ * <h3>Example</h3>
+ * @codestart
+ * $.Class("MyClass",{},{})
+ * var mc = MyClass.newInstance.apply(null, new Array(parseInt(Math.random()*10,10))
+ * @codeend
+ * @return {class} instance of the class
+ */
+ newInstance: function() {
+ // get a raw instance objet (init is not called)
+ var inst = this.rawInstance(),
+ args;
+
+ // call setup if there is a setup
+ if ( inst.setup ) {
+ args = inst.setup.apply(inst, arguments);
+ }
+ // call init if there is an init, if setup returned args, use those as the arguments
+ if ( inst.init ) {
+ inst.init.apply(inst, isArray(args) ? args : arguments);
+ }
+ return inst;
+ },
+ /**
+ * Setup gets called on the inherting class with the base class followed by the
+ * inheriting class's raw properties.
+ *
+ * Setup will deeply extend a static defaults property on the base class with
+ * properties on the base class. For example:
+ *
+ * $.Class("MyBase",{
+ * defaults : {
+ * foo: 'bar'
+ * }
+ * },{})
+ *
+ * MyBase("Inheriting",{
+ * defaults : {
+ * newProp : 'newVal'
+ * }
+ * },{}
+ *
+ * Inheriting.defaults -> {foo: 'bar', 'newProp': 'newVal'}
+ *
+ * @param {Object} baseClass the base class that is being inherited from
+ * @param {String} fullName the name of the new class
+ * @param {Object} staticProps the static properties of the new class
+ * @param {Object} protoProps the prototype properties of the new class
+ */
+ setup: function( baseClass, fullName ) {
+ // set defaults as the merger of the parent defaults and this object's defaults
+ this.defaults = extend(true, {}, baseClass.defaults, this.defaults);
+ return arguments;
+ },
+ rawInstance: function() {
+ // prevent running init
+ initializing = true;
+ var inst = new this();
+ initializing = false;
+ // allow running init
+ return inst;
+ },
+ /**
+ * Extends a class with new static and prototype functions. There are a variety of ways
+ * to use extend:
+ *
+ * // with className, static and prototype functions
+ * $.Class('Task',{ STATIC },{ PROTOTYPE })
+ * // with just classname and prototype functions
+ * $.Class('Task',{ PROTOTYPE })
+ * // with just a className
+ * $.Class('Task')
+ *
+ * You no longer have to use <code>.extend</code>. Instead, you can pass those options directly to
+ * $.Class (and any inheriting classes):
+ *
+ * // with className, static and prototype functions
+ * $.Class('Task',{ STATIC },{ PROTOTYPE })
+ * // with just classname and prototype functions
+ * $.Class('Task',{ PROTOTYPE })
+ * // with just a className
+ * $.Class('Task')
+ *
+ * @param {String} [fullName] the classes name (used for classes w/ introspection)
+ * @param {Object} [klass] the new classes static/class functions
+ * @param {Object} [proto] the new classes prototype functions
+ *
+ * @return {jQuery.Class} returns the new class
+ */
+ extend: function( fullName, klass, proto ) {
+ // figure out what was passed and normalize it
+ if ( typeof fullName != 'string' ) {
+ proto = klass;
+ klass = fullName;
+ fullName = null;
+ }
+ if (!proto ) {
+ proto = klass;
+ klass = null;
+ }
+
+ proto = proto || {};
+ var _super_class = this,
+ _super = this[STR_PROTOTYPE],
+ name, shortName, namespace, prototype;
+
+ // Instantiate a base class (but only create the instance,
+ // don't run the init constructor)
+ initializing = true;
+ prototype = new this();
+ initializing = false;
+
+ // Copy the properties over onto the new prototype
+ inheritProps(proto, _super, prototype);
+
+ // The dummy class constructor
+ function Class() {
+ // All construction is actually done in the init method
+ if ( initializing ) return;
+
+ // we are being called w/o new, we are extending
+ if ( this.constructor !== Class && arguments.length ) {
+ return arguments.callee.extend.apply(arguments.callee, arguments)
+ } else { //we are being called w/ new
+ return this.Class.newInstance.apply(this.Class, arguments)
+ }
+ }
+ // Copy old stuff onto class
+ for ( name in this ) {
+ if ( this.hasOwnProperty(name) ) {
+ Class[name] = this[name];
+ }
+ }
+
+ // copy new static props on class
+ inheritProps(klass, this, Class);
+
+ // do namespace stuff
+ if ( fullName ) {
+
+ var parts = fullName.split(/\./),
+ shortName = parts.pop(),
+ current = getObject(parts.join('.'), window, true),
+ namespace = current;
+
+ //!steal-remove-start
+ if (!Class.nameOk ) {
+ //steal.dev.isHappyName(fullName)
+ }
+ if(current[shortName]){
+ steal.dev.warn("class.js There's already something called "+fullName)
+ }
+ //!steal-remove-end
+ current[shortName] = Class;
+ }
+
+ // set things that can't be overwritten
+ extend(Class, {
+ prototype: prototype,
+ /**
+ * @attribute namespace
+ * The namespaces object
+ *
+ * $.Class("MyOrg.MyClass",{},{})
+ * MyOrg.MyClass.namespace //-> MyOrg
+ *
+ */
+ namespace: namespace,
+ /**
+ * @attribute shortName
+ * The name of the class without its namespace, provided for introspection purposes.
+ *
+ * $.Class("MyOrg.MyClass",{},{})
+ * MyOrg.MyClass.shortName //-> 'MyClass'
+ * MyOrg.MyClass.fullName //-> 'MyOrg.MyClass'
+ *
+ */
+ shortName: shortName,
+ constructor: Class,
+ /**
+ * @attribute fullName
+ * The full name of the class, including namespace, provided for introspection purposes.
+ *
+ * $.Class("MyOrg.MyClass",{},{})
+ * MyOrg.MyClass.shortName //-> 'MyClass'
+ * MyOrg.MyClass.fullName //-> 'MyOrg.MyClass'
+ *
+ */
+ fullName: fullName
+ });
+
+ //make sure our prototype looks nice
+ Class[STR_PROTOTYPE].Class = Class[STR_PROTOTYPE].constructor = Class;
+
+
+
+ // call the class setup
+ var args = Class.setup.apply(Class, concatArgs([_super_class],arguments));
+
+ // call the class init
+ if ( Class.init ) {
+ Class.init.apply(Class, args || concatArgs([_super_class],arguments));
+ }
+
+ /* @Prototype*/
+ return Class;
+ /**
+ * @function setup
+ * If a setup method is provided, it is called when a new
+ * instances is created. It gets passed the same arguments that
+ * were given to the Class constructor function (<code> new Class( arguments ... )</code>).
+ *
+ * $.Class("MyClass",
+ * {
+ * setup: function( val ) {
+ * this.val = val;
+ * }
+ * })
+ * var mc = new MyClass("Check Check")
+ * mc.val //-> 'Check Check'
+ *
+ * Setup is called before [jQuery.Class.prototype.init init]. If setup
+ * return an array, those arguments will be used for init.
+ *
+ * $.Class("jQuery.Controller",{
+ * setup : function(htmlElement, rawOptions){
+ * return [$(htmlElement),
+ * $.extend({}, this.Class.defaults, rawOptions )]
+ * }
+ * })
+ *
+ * <div class='whisper'>PRO TIP:
+ * Setup functions are used to normalize constructor arguments and provide a place for
+ * setup code that extending classes don't have to remember to call _super to
+ * run.
+ * </div>
+ *
+ * Setup is not defined on $.Class itself, so calling super in inherting classes
+ * will break. Don't do the following:
+ *
+ * $.Class("Thing",{
+ * setup : function(){
+ * this._super(); // breaks!
+ * }
+ * })
+ *
+ * @return {Array|undefined} If an array is return, [jQuery.Class.prototype.init] is
+ * called with those arguments; otherwise, the original arguments are used.
+ */
+ //break up
+ /**
+ * @function init
+ * If an <code>init</code> method is provided, it gets called when a new instance
+ * is created. Init gets called after [jQuery.Class.prototype.setup setup], typically with the
+ * same arguments passed to the Class
+ * constructor: (<code> new Class( arguments ... )</code>).
+ *
+ * $.Class("MyClass",
+ * {
+ * init: function( val ) {
+ * this.val = val;
+ * }
+ * })
+ * var mc = new MyClass(1)
+ * mc.val //-> 1
+ *
+ * [jQuery.Class.prototype.setup Setup] is able to modify the arguments passed to init. Read
+ * about it there.
+ *
+ */
+ //Breaks up code
+ /**
+ * @attribute constructor
+ *
+ * A reference to the Class (or constructor function). This allows you to access
+ * a class's static properties from an instance.
+ *
+ * ### Quick Example
+ *
+ * // a class with a static property
+ * $.Class("MyClass", {staticProperty : true}, {});
+ *
+ * // a new instance of myClass
+ * var mc1 = new MyClass();
+ *
+ * // read the static property from the instance:
+ * mc1.constructor.staticProperty //-> true
+ *
+ * Getting static properties with the constructor property, like
+ * [jQuery.Class.static.fullName fullName], is very common.
+ *
+ */
+ }
+
+ })
+
+
+
+
+
+ clss.callback = clss[STR_PROTOTYPE].callback = clss[STR_PROTOTYPE].
+ /**
+ * @function proxy
+ * Returns a method that sets 'this' to the current instance. This does the same thing as
+ * and is described better in [jQuery.Class.static.proxy].
+ * The only difference is this proxy works
+ * on a instance instead of a class.
+ * @param {String|Array} fname If a string, it represents the function to be called.
+ * If it is an array, it will call each function in order and pass the return value of the prior function to the
+ * next function.
+ * @return {Function} the callback function
+ */
+ proxy = clss.proxy;
+
+
+})();
View
205 labs/architecture-examples/javascriptmvc/jquery/class/class_test.js
@@ -0,0 +1,205 @@
+steal("jquery/class") //load your app
+ .then('funcunit/qunit').then(function(){
+
+module("jquery/class");
+
+test("Creating", function(){
+
+ jQuery.Class.extend("Animal",
+ {
+ count: 0,
+ test: function() {
+ return this.match ? true : false
+ }
+ },
+ {
+ init: function() {
+ this.Class.count++;
+ this.eyes = false;
+ }
+ }
+ );
+ Animal.extend("Dog",
+ {
+ match : /abc/
+ },
+ {
+ init: function() {
+ this._super();
+ },
+ talk: function() {
+ return "Woof";
+ }
+ });
+ Dog.extend("Ajax",
+ {
+ count : 0
+ },
+ {
+ init: function( hairs ) {
+ this._super();
+ this.hairs = hairs;
+ this.setEyes();
+
+ },
+ setEyes: function() {
+ this.eyes = true;
+ }
+ });
+ new Dog();
+ new Animal();
+ new Animal();
+ var ajax = new Ajax(1000);
+
+ equals(2, Animal.count, "right number of animals");
+ equals(1, Dog.count, "right number of animals")
+ ok(Dog.match, "right number of animals")
+ ok(!Animal.match, "right number of animals")
+ ok(Dog.test(), "right number of animals")
+ ok(!Animal.test(), "right number of animals")
+ equals(1, Ajax.count, "right number of animals")
+ equals(2, Animal.count, "right number of animals");
+ equals(true, ajax.eyes, "right number of animals");
+ equals(1000, ajax.hairs, "right number of animals");
+})
+
+
+test("new instance",function(){
+ var d = Ajax.newInstance(6);
+ equals(6, d.hairs);
+})
+
+
+test("namespaces",function(){
+ var fb = $.Class.extend("Foo.Bar")
+ ok(Foo.Bar === fb, "returns class")
+ equals(fb.shortName, "Bar", "short name is right");
+ equals(fb.fullName, "Foo.Bar","fullName is right")
+
+})
+
+test("setups", function(){
+ var order = 0,
+ staticSetup,
+ staticSetupArgs,
+ staticInit,
+ staticInitArgs,
+ protoSetup,
+ protoInitArgs,
+ protoInit,
+ staticProps = {
+ setup: function() {
+ staticSetup = ++order;
+ staticSetupArgs = arguments;
+ return ["something"]
+ },
+ init: function() {
+ staticInit = ++order;
+ staticInitArgs = arguments;
+ }
+ },
+ protoProps = {
+ setup: function( name ) {
+ protoSetup = ++order;
+ return ["Ford: "+name];
+ },
+ init: function() {
+ protoInit = ++order;
+ protoInitArgs = arguments;
+ }
+ }
+ $.Class.extend("Car",staticProps,protoProps);
+
+ var geo = new Car("geo");
+ equals(staticSetup, 1);
+ equals(staticInit, 2);
+ equals(protoSetup, 3);
+ equals(protoInit, 4);
+
+ same($.makeArray(staticInitArgs), ["something"] )
+ same($.makeArray(protoInitArgs),["Ford: geo"] )
+
+ same($.makeArray(staticSetupArgs),[$.Class, "Car",staticProps, protoProps] ,"static construct");
+
+
+ //now see if staticSetup gets called again ...
+ Car.extend("Truck");
+ equals(staticSetup, 5, "Static setup is called if overwriting");
+
+});
+
+test("callback", function(){
+ var curVal = 0;
+ $.Class.extend("Car",{
+ show: function( value ) {
+ equals(curVal, value)
+ }
+ },{
+ show: function( value ) {
+
+ }
+ })
+ var cb = Car.callback('show');
+ curVal = 1;
+ cb(1)
+
+ curVal = 2;
+ var cb2 = Car.callback('show',2)
+ cb2();
+});
+
+test("callback error", 1,function(){
+ $.Class.extend("Car",{
+ show: function( value ) {
+ equals(curVal, value)
+ }
+ },{
+ show: function( value ) {
+
+ }
+ })
+ try{
+ Car.callback('huh');
+ ok(false, "I should have errored")
+ }catch(e){
+ ok(true, "Error was thrown")
+ }
+})
+
+test("Creating without extend", function(){
+ $.Class("Bar",{
+ ok : function(){
+ ok(true, "ok called")
+ }
+ });
+ new Bar().ok();
+
+ Bar("Foo",{
+ dude : function(){
+ ok(true, "dude called")
+ }
+ });
+ new Foo().dude(true);
+})
+
+
+/* Not sure I want to fix this yet.
+test("Super in derived when parent doesn't have init", function(){
+ $.Class("Parent",{
+ });
+
+ Parent("Derived",{
+ init : function(){
+ this._super();
+ }
+ });
+
+ try {
+ new Derived();
+ ok(true, "Can call super in init safely")
+ } catch (e) {
+ ok(false, "Failed to call super in init with error: " + e)
+ }
+})*/
+
+});
View
15 labs/architecture-examples/javascriptmvc/jquery/class/qunit.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="../../funcunit/qunit/qunit.css" />
+ </head>
+ <body>
+
+ <h1 id="qunit-header">Class Test Suite</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"></ol>
+ <div id="qunit-test-area"></div>
+ <script type='text/javascript' src='../../steal/steal.js?jquery/class/class_test.js'></script>
+ </body>
+</html>
View
88 labs/architecture-examples/javascriptmvc/jquery/controller/controller.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+ <head>
+ <title>Controller Example</title>
+ <style type='text/css'>
+ body {font-family: verdana}
+ .tabs {
+
+ padding: 0px; margin: 0px;
+ }
+ .tabs li {
+ float: left;
+ padding: 10px;
+ background-color: #F6F6F6;
+ list-style: none;
+ margin-left: 10px;
+ }
+ .tabs li a {
+ color: #1C94C4;
+ font-weight: bold;
+ text-decoration: none;
+ }
+ .tabs li.active a {
+ color: #F6A828;
+ cursor: default;
+ }
+ .tab {
+ border: solid 1px #F6A828;
+ }
+ /* clearfix from jQueryUI */
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+ .ui-helper-clearfix { display: inline-block; }
+ /* required comment for clearfix to work in Opera \*/
+ * html .ui-helper-clearfix { height:1%; }
+ .ui-helper-clearfix { display:block; }
+ /* end clearfix */
+ </style>
+ </head>
+ <body>
+<div id="demo-html">
+<ul id='tabs' class='ui-helper-clearfix''>
+ <li><a href='#tab1'>Tab 1</a></li>
+ <li><a href='#tab2'>Tab 2</a></li>
+ <li><a href='#tab3'>Tab 3</a></li>
+</ul>
+<div id='tab1' class='tab'>Tab 1 Content</div>
+<div id='tab2' class='tab'>Tab 2 Content</div>
+<div id='tab3' class='tab'>Tab 3 Content</div>
+</div>
+<script type='text/javascript' src='../../steal/steal.js'></script>
+<script type='text/javascript'>
+steal("jquery/controller", function(){
+// create a new Tabs class
+$.Controller("Tabs",{
+
+ // initialize widget
+ init : function(el){
+
+ // activate the first tab
+ $(el).children("li:first").addClass('active')
+
+ // hide the other tabs
+ var tab = this.tab;
+ this.element.children("li:gt(0)").each(function(){
+ tab($(this)).hide()
+ })
+ },
+
+ // helper function finds the tab for a given li
+ tab : function(li){
+ return $(li.find("a").attr("href"))
+ },
+
+ // hides old active tab, shows new one
+ "li click" : function(el, ev){
+ ev.preventDefault();
+ this.tab(this.find('.active').removeClass('active')).hide()
+ this.tab(el.addClass('active')).show();
+ }
+})
+
+// adds the controller to the element
+$("#tabs").tabs();
+})
+</script>
+ </body>
+</html>
View
1,089 labs/architecture-examples/javascriptmvc/jquery/controller/controller.js
@@ -0,0 +1,1089 @@
+steal('jquery/class', 'jquery/lang/string', 'jquery/event/destroyed', function( $ ) {
+ // ------- HELPER FUNCTIONS ------
+
+ // Binds an element, returns a function that unbinds
+ var bind = function( el, ev, callback ) {
+ var wrappedCallback,
+ binder = el.bind && el.unbind ? el : $(isFunction(el) ? [el] : el);
+ //this is for events like >click.
+ if ( ev.indexOf(">") === 0 ) {
+ ev = ev.substr(1);
+ wrappedCallback = function( event ) {
+ if ( event.target === el ) {
+ callback.apply(this, arguments);
+ }
+ };
+ }
+ binder.bind(ev, wrappedCallback || callback);
+ // if ev name has >, change the name and bind
+ // in the wrapped callback, check that the element matches the actual element
+ return function() {
+ binder.unbind(ev, wrappedCallback || callback);
+ el = ev = callback = wrappedCallback = null;
+ };
+ },
+ makeArray = $.makeArray,
+ isArray = $.isArray,
+ isFunction = $.isFunction,
+ extend = $.extend,
+ Str = $.String,
+ each = $.each,
+
+ STR_PROTOTYPE = 'prototype',
+ STR_CONSTRUCTOR = 'constructor',
+ slice = Array[STR_PROTOTYPE].slice,
+
+ // Binds an element, returns a function that unbinds
+ delegate = function( el, selector, ev, callback ) {
+ var binder = el.delegate && el.undelegate ? el : $(isFunction(el) ? [el] : el)
+ binder.delegate(selector, ev, callback);
+ return function() {
+ binder.undelegate(selector, ev, callback);
+ binder = el = ev = callback = selector = null;
+ };
+ },
+
+ // calls bind or unbind depending if there is a selector
+ binder = function( el, ev, callback, selector ) {
+ return selector ? delegate(el, selector, ev, callback) : bind(el, ev, callback);
+ },
+
+ // moves 'this' to the first argument, wraps it with jQuery if it's an element
+ shifter = function shifter(context, name) {
+ var method = typeof name == "string" ? context[name] : name;
+ return function() {
+ context.called = name;
+ return method.apply(context, [this.nodeName ? $(this) : this].concat( slice.call(arguments, 0) ) );
+ };
+ },
+ // matches dots
+ dotsReg = /\./g,
+ // matches controller
+ controllersReg = /_?controllers?/ig,
+ //used to remove the controller from the name
+ underscoreAndRemoveController = function( className ) {
+ return Str.underscore(className.replace("jQuery.", "").replace(dotsReg, '_').replace(controllersReg, ""));
+ },
+ // checks if it looks like an action
+ actionMatcher = /[^\w]/,
+ // handles parameterized action names
+ parameterReplacer = /\{([^\}]+)\}/g,
+ breaker = /^(?:(.*?)\s)?([\w\.\:>]+)$/,
+ basicProcessor,
+ data = function(el, data){
+ return $.data(el, "controllers", data)
+ };
+ /**
+ * @class jQuery.Controller
+ * @parent jquerymx
+ * @plugin jquery/controller
+ * @download http://jmvcsite.heroku.com/pluginify?plugins[]=jquery/controller/controller.js
+ * @test jquery/controller/qunit.html
+ * @inherits jQuery.Class
+ * @description jQuery widget factory.
+ *
+ * jQuery.Controller helps create organized, memory-leak free, rapidly performing
+ * jQuery widgets. Its extreme flexibility allows it to serve as both
+ * a traditional View and a traditional Controller.
+ *
+ * This means it is used to
+ * create things like tabs, grids, and contextmenus as well as
+ * organizing them into higher-order business rules.
+ *
+ * Controllers make your code deterministic, reusable, organized and can tear themselves
+ * down auto-magically. Read about [http://jupiterjs.com/news/writing-the-perfect-jquery-plugin
+ * the theory behind controller] and
+ * a [http://jupiterjs.com/news/organize-jquery-widgets-with-jquery-controller walkthrough of its features]
+ * on Jupiter's blog. [mvc.controller Get Started with jQueryMX] also has a great walkthrough.
+ *
+ * Controller inherits from [jQuery.Class $.Class] and makes heavy use of
+ * [http://api.jquery.com/delegate/ event delegation]. Make sure
+ * you understand these concepts before using it.
+ *
+ * ## Basic Example
+ *
+ * Instead of
+ *
+ *
+ * $(function(){
+ * $('#tabs').click(someCallbackFunction1)
+ * $('#tabs .tab').click(someCallbackFunction2)
+ * $('#tabs .delete click').click(someCallbackFunction3)
+ * });
+ *
+ * do this
+ *
+ * $.Controller('Tabs',{
+ * click: function() {...},
+ * '.tab click' : function() {...},
+ * '.delete click' : function() {...}
+ * })
+ * $('#tabs').tabs();
+ *
+ *
+ * ## Tabs Example
+ *
+ * @demo jquery/controller/controller.html
+ *
+ * ## Using Controller
+ *
+ * Controller helps you build and organize jQuery plugins. It can be used
+ * to build simple widgets, like a slider, or organize multiple
+ * widgets into something greater.
+ *
+ * To understand how to use Controller, you need to understand
+ * the typical lifecycle of a jQuery widget and how that maps to
+ * controller's functionality:
+ *
+ * ### A controller class is created.
+ *
+ * $.Controller("MyWidget",
+ * {
+ * defaults : {
+ * message : "Remove Me"
+ * }
+ * },
+ * {
+ * init : function(rawEl, rawOptions){
+ * this.element.append(
+ * "<div>"+this.options.message+"</div>"
+ * );
+ * },
+ * "div click" : function(div, ev){
+ * div.remove();
+ * }
+ * })
+ *
+ * This creates a <code>$.fn.my_widget</code> jQuery helper function
+ * that can be used to create a new controller instance on an element. Find
+ * more information [jquery.controller.plugin here] about the plugin gets created
+ * and the rules around its name.
+ *
+ * ### An instance of controller is created on an element
+ *
+ * $('.thing').my_widget(options) // calls new MyWidget(el, options)
+ *
+ * This calls <code>new MyWidget(el, options)</code> on
+ * each <code>'.thing'</code> element.
+ *
+ * When a new [jQuery.Class Class] instance is created, it calls the class's
+ * prototype setup and init methods. Controller's [jQuery.Controller.prototype.setup setup]
+ * method:
+ *
+ * - Sets [jQuery.Controller.prototype.element this.element] and adds the controller's name to element's className.
+ * - Merges passed in options with defaults object and sets it as [jQuery.Controller.prototype.options this.options]
+ * - Saves a reference to the controller in <code>$.data</code>.
+ * - [jquery.controller.listening Binds all event handler methods].
+ *
+ *
+ * ### The controller responds to events
+ *
+ * Typically, Controller event handlers are automatically bound. However, there are
+ * multiple ways to [jquery.controller.listening listen to events] with a controller.
+ *
+ * Once an event does happen, the callback function is always called with 'this'
+ * referencing the controller instance. This makes it easy to use helper functions and
+ * save state on the controller.
+ *
+ *
+ * ### The widget is destroyed
+ *
+ * If the element is removed from the page, the
+ * controller's [jQuery.Controller.prototype.destroy] method is called.
+ * This is a great place to put any additional teardown functionality.
+ *
+ * You can also teardown a controller programatically like:
+ *
+ * $('.thing').my_widget('destroy');
+ *
+ * ## Todos Example
+ *
+ * Lets look at a very basic example -
+ * a list of todos and a button you want to click to create a new todo.
+ * Your HTML might look like:
+ *
+ * @codestart html
+ * &lt;div id='todos'>
+ * &lt;ol>
+ * &lt;li class="todo">Laundry&lt;/li>
+ * &lt;li class="todo">Dishes&lt;/li>
+ * &lt;li class="todo">Walk Dog&lt;/li>
+ * &lt;/ol>
+ * &lt;a class="create">Create&lt;/a>
+ * &lt;/div>
+ * @codeend
+ *
+ * To add a mousover effect and create todos, your controller might look like:
+ *
+ * $.Controller('Todos',{
+ * ".todo mouseover" : function( el, ev ) {
+ * el.css("backgroundColor","red")
+ * },
+ * ".todo mouseout" : function( el, ev ) {
+ * el.css("backgroundColor","")
+ * },
+ * ".create click" : function() {
+ * this.find("ol").append("<li class='todo'>New Todo</li>");
+ * }
+ * })
+ *
+ * Now that you've created the controller class, you've must attach the event handlers on the '#todos' div by
+ * creating [jQuery.Controller.prototype.setup|a new controller instance]. There are 2 ways of doing this.
+ *
+ * @codestart
+ * //1. Create a new controller directly:
+ * new Todos($('#todos'));
+ * //2. Use jQuery function
+ * $('#todos').todos();
+ * @codeend
+ *
+ * ## Controller Initialization
+ *
+ * It can be extremely useful to add an init method with
+ * setup functionality for your widget.
+ *
+ * In the following example, I create a controller that when created, will put a message as the content of the element:
+ *
+ * $.Controller("SpecialController",
+ * {
+ * init: function( el, message ) {
+ * this.element.html(message)
+ * }
+ * })
+ * $(".special").special("Hello World")
+ *
+ * ## Removing Controllers
+ *
+ * Controller removal is built into jQuery. So to remove a controller, you just have to remove its element:
+ *
+ * @codestart
+ * $(".special_controller").remove()
+ * $("#containsControllers").html("")
+ * @codeend
+ *
+ * It's important to note that if you use raw DOM methods (<code>innerHTML, removeChild</code>), the controllers won't be destroyed.
+ *
+ * If you just want to remove controller functionality, call destroy on the controller instance:
+ *
+ * @codestart
+ * $(".special_controller").controller().destroy()
+ * @codeend
+ *
+ * ## Accessing Controllers
+ *
+ * Often you need to get a reference to a controller, there are a few ways of doing that. For the
+ * following example, we assume there are 2 elements with <code>className="special"</code>.
+ *
+ * @codestart
+ * //creates 2 foo controllers
+ * $(".special").foo()
+ *
+ * //creates 2 bar controllers
+ * $(".special").bar()
+ *
+ * //gets all controllers on all elements:
+ * $(".special").controllers() //-> [foo, bar, foo, bar]
+ *
+ * //gets only foo controllers
+ * $(".special").controllers(FooController) //-> [foo, foo]
+ *
+ * //gets all bar controllers
+ * $(".special").controllers(BarController) //-> [bar, bar]
+ *
+ * //gets first controller
+ * $(".special").controller() //-> foo
+ *
+ * //gets foo controller via data
+ * $(".special").data("controllers")["FooController"] //-> foo
+ * @codeend
+ *
+ * ## Calling methods on Controllers
+ *
+ * Once you have a reference to an element, you can call methods on it. However, Controller has
+ * a few shortcuts:
+ *
+ * @codestart
+ * //creates foo controller
+ * $(".special").foo({name: "value"})
+ *
+ * //calls FooController.prototype.update
+ * $(".special").foo({name: "value2"})
+ *
+ * //calls FooController.prototype.bar
+ * $(".special").foo("bar","something I want to pass")
+ * @codeend
+ *
+ * These methods let you call one controller from another controller.
+ *
+ */
+ $.Class("jQuery.Controller",
+ /**
+ * @Static
+ */
+ {
+ /**
+ * Does 2 things:
+ *
+ * - Creates a jQuery helper for this controller.</li>
+ * - Calculates and caches which functions listen for events.</li>
+ *
+ * ### jQuery Helper Naming Examples
+ *
+ *
+ * "TaskController" -> $().task_controller()
+ * "Controllers.Task" -> $().controllers_task()
+ *
+ */
+ setup: function() {
+ // Allow contollers to inherit "defaults" from superclasses as it done in $.Class
+ this._super.apply(this, arguments);
+
+ // if you didn't provide a name, or are controller, don't do anything
+ if (!this.shortName || this.fullName == "jQuery.Controller" ) {
+ return;
+ }
+ // cache the underscored names
+ this._fullName = underscoreAndRemoveController(this.fullName);
+ this._shortName = underscoreAndRemoveController(this.shortName);
+
+ var controller = this,
+ /**
+ * @attribute pluginName
+ * Setting the <code>pluginName</code> property allows you
+ * to change the jQuery plugin helper name from its
+ * default value.
+ *
+ * $.Controller("Mxui.Layout.Fill",{
+ * pluginName: "fillWith"
+ * },{});
+ *
+ * $("#foo").fillWith();
+ */
+ pluginname = this.pluginName || this._fullName,
+ funcName, forLint;
+
+ // create jQuery plugin
+ if (!$.fn[pluginname] ) {
+ $.fn[pluginname] = function( options ) {
+
+ var args = makeArray(arguments),
+ //if the arg is a method on this controller
+ isMethod = typeof options == "string" && isFunction(controller[STR_PROTOTYPE][options]),
+ meth = args[0];
+ return this.each(function() {
+ //check if created
+ var controllers = data(this),
+ //plugin is actually the controller instance
+ plugin = controllers && controllers[pluginname];
+
+ if ( plugin ) {
+ if ( isMethod ) {
+ // call a method on the controller with the remaining args
+ plugin[meth].apply(plugin, args.slice(1));
+ } else {
+ // call the plugin's update method
+ plugin.update.apply(plugin, args);
+ }
+
+ } else {
+ //create a new controller instance
+ controller.newInstance.apply(controller, [this].concat(args));
+ }
+ });
+ };
+ }
+
+ // make sure listensTo is an array
+ //!steal-remove-start
+ if (!isArray(this.listensTo) ) {
+ throw "