sproutcore 0.9.0

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 (270) hide show
  1. data/History.txt +4 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +269 -0
  4. data/README.txt +67 -0
  5. data/Rakefile +4 -0
  6. data/app_generators/sproutcore/USAGE +5 -0
  7. data/app_generators/sproutcore/sproutcore_generator.rb +66 -0
  8. data/app_generators/sproutcore/templates/README +77 -0
  9. data/app_generators/sproutcore/templates/environment.yml +4 -0
  10. data/bin/sc-build +145 -0
  11. data/bin/sc-gen +24 -0
  12. data/bin/sc-server +63 -0
  13. data/bin/sproutcore +21 -0
  14. data/clients/sc_docs/controllers/docs.js +118 -0
  15. data/clients/sc_docs/core.js +19 -0
  16. data/clients/sc_docs/english.lproj/body.css +159 -0
  17. data/clients/sc_docs/english.lproj/body.rhtml +33 -0
  18. data/clients/sc_docs/english.lproj/controls.css +0 -0
  19. data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
  20. data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
  21. data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
  22. data/clients/sc_docs/english.lproj/images/indicator.gif +0 -0
  23. data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
  24. data/clients/sc_docs/english.lproj/no_docs.rhtml +7 -0
  25. data/clients/sc_docs/english.lproj/strings.js +14 -0
  26. data/clients/sc_docs/english.lproj/warning.rhtml +6 -0
  27. data/clients/sc_docs/fixtures/doc.js +11 -0
  28. data/clients/sc_docs/main.js +21 -0
  29. data/clients/sc_docs/models/doc.js +9 -0
  30. data/clients/sc_docs/tests/controllers/docs.rhtml +21 -0
  31. data/clients/sc_docs/tests/models/doc.rhtml +21 -0
  32. data/clients/sc_docs/tests/views/doc_frame.rhtml +21 -0
  33. data/clients/sc_docs/tests/views/doc_label_view.rhtml +21 -0
  34. data/clients/sc_docs/views/doc_frame.js +33 -0
  35. data/clients/sc_docs/views/doc_label.js +20 -0
  36. data/clients/sc_test_runner/controllers/runner.js +175 -0
  37. data/clients/sc_test_runner/core.js +19 -0
  38. data/clients/sc_test_runner/english.lproj/body.css +151 -0
  39. data/clients/sc_test_runner/english.lproj/body.rhtml +35 -0
  40. data/clients/sc_test_runner/english.lproj/controls.css +0 -0
  41. data/clients/sc_test_runner/english.lproj/icons/small/next.png +0 -0
  42. data/clients/sc_test_runner/english.lproj/icons/small/reset.png +0 -0
  43. data/clients/sc_test_runner/english.lproj/images/gradients.png +0 -0
  44. data/clients/sc_test_runner/english.lproj/images/indicator.gif +0 -0
  45. data/clients/sc_test_runner/english.lproj/images/toolbar.png +0 -0
  46. data/clients/sc_test_runner/english.lproj/no_tests.rhtml +6 -0
  47. data/clients/sc_test_runner/english.lproj/strings.js +14 -0
  48. data/clients/sc_test_runner/english.lproj/warning.rhtml +6 -0
  49. data/clients/sc_test_runner/fixtures/test.js +12 -0
  50. data/clients/sc_test_runner/main.js +26 -0
  51. data/clients/sc_test_runner/models/test.js +11 -0
  52. data/clients/sc_test_runner/views/runner_frame.js +72 -0
  53. data/clients/sc_test_runner/views/test_label.js +20 -0
  54. data/config/hoe.rb +70 -0
  55. data/config/requirements.rb +17 -0
  56. data/environment.yml +9 -0
  57. data/frameworks/prototype/prototype.js +4186 -0
  58. data/frameworks/sproutcore/Core.js +378 -0
  59. data/frameworks/sproutcore/README +3 -0
  60. data/frameworks/sproutcore/controllers/array.js +236 -0
  61. data/frameworks/sproutcore/controllers/collection.js +305 -0
  62. data/frameworks/sproutcore/controllers/controller.js +323 -0
  63. data/frameworks/sproutcore/controllers/object.js +372 -0
  64. data/frameworks/sproutcore/drag/drag.js +549 -0
  65. data/frameworks/sproutcore/drag/drag_data_source.js +32 -0
  66. data/frameworks/sproutcore/drag/drag_source.js +64 -0
  67. data/frameworks/sproutcore/drag/drop_target.js +153 -0
  68. data/frameworks/sproutcore/english.lproj/blank.gif +0 -0
  69. data/frameworks/sproutcore/english.lproj/buttons.css +589 -0
  70. data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
  71. data/frameworks/sproutcore/english.lproj/inline_text_editor.css +21 -0
  72. data/frameworks/sproutcore/english.lproj/menu.css +121 -0
  73. data/frameworks/sproutcore/english.lproj/panels/background-fat.jpg +0 -0
  74. data/frameworks/sproutcore/english.lproj/panels/background-thin.jpg +0 -0
  75. data/frameworks/sproutcore/english.lproj/panels/bottom-edge.png +0 -0
  76. data/frameworks/sproutcore/english.lproj/panels/bottom-left-corner.png +0 -0
  77. data/frameworks/sproutcore/english.lproj/panels/bottom-right-corner.png +0 -0
  78. data/frameworks/sproutcore/english.lproj/panels/left-edge.png +0 -0
  79. data/frameworks/sproutcore/english.lproj/panels/overlay.png +0 -0
  80. data/frameworks/sproutcore/english.lproj/panels/right-edge.png +0 -0
  81. data/frameworks/sproutcore/english.lproj/panels/top-edge.png +0 -0
  82. data/frameworks/sproutcore/english.lproj/panels/top-left-corner.png +0 -0
  83. data/frameworks/sproutcore/english.lproj/panels/top-right-corner.png +0 -0
  84. data/frameworks/sproutcore/english.lproj/panes.css +155 -0
  85. data/frameworks/sproutcore/english.lproj/picker.css +22 -0
  86. data/frameworks/sproutcore/english.lproj/strings.js +15 -0
  87. data/frameworks/sproutcore/english.lproj/tab.css +23 -0
  88. data/frameworks/sproutcore/english.lproj/tests.css +67 -0
  89. data/frameworks/sproutcore/english.lproj/theme.css +77 -0
  90. data/frameworks/sproutcore/foundation/animator.js +670 -0
  91. data/frameworks/sproutcore/foundation/application.js +199 -0
  92. data/frameworks/sproutcore/foundation/array.js +348 -0
  93. data/frameworks/sproutcore/foundation/benchmark.js +211 -0
  94. data/frameworks/sproutcore/foundation/binding.js +384 -0
  95. data/frameworks/sproutcore/foundation/date.js +357 -0
  96. data/frameworks/sproutcore/foundation/error.js +39 -0
  97. data/frameworks/sproutcore/foundation/input_manager.js +153 -0
  98. data/frameworks/sproutcore/foundation/json.js +296 -0
  99. data/frameworks/sproutcore/foundation/mock.js +42 -0
  100. data/frameworks/sproutcore/foundation/node_descriptor.js +56 -0
  101. data/frameworks/sproutcore/foundation/object.js +777 -0
  102. data/frameworks/sproutcore/foundation/observable.js +451 -0
  103. data/frameworks/sproutcore/foundation/page.js +63 -0
  104. data/frameworks/sproutcore/foundation/path_module.js +413 -0
  105. data/frameworks/sproutcore/foundation/responder.js +310 -0
  106. data/frameworks/sproutcore/foundation/routes.js +371 -0
  107. data/frameworks/sproutcore/foundation/run_loop.js +21 -0
  108. data/frameworks/sproutcore/foundation/server.js +491 -0
  109. data/frameworks/sproutcore/foundation/set.js +96 -0
  110. data/frameworks/sproutcore/foundation/string.js +149 -0
  111. data/frameworks/sproutcore/foundation/undo_manager.js +186 -0
  112. data/frameworks/sproutcore/foundation/unittest.js +622 -0
  113. data/frameworks/sproutcore/foundation/utils.js +61 -0
  114. data/frameworks/sproutcore/globals/panels.js +182 -0
  115. data/frameworks/sproutcore/globals/popups.js +60 -0
  116. data/frameworks/sproutcore/globals/window.js +381 -0
  117. data/frameworks/sproutcore/lib/index.rhtml +66 -0
  118. data/frameworks/sproutcore/models/collection.js +395 -0
  119. data/frameworks/sproutcore/models/record.js +622 -0
  120. data/frameworks/sproutcore/models/store.js +295 -0
  121. data/frameworks/sproutcore/panes/dialog.js +16 -0
  122. data/frameworks/sproutcore/panes/manager.js +164 -0
  123. data/frameworks/sproutcore/panes/menu.js +45 -0
  124. data/frameworks/sproutcore/panes/overlay.js +231 -0
  125. data/frameworks/sproutcore/panes/pane.js +90 -0
  126. data/frameworks/sproutcore/panes/panel.js +19 -0
  127. data/frameworks/sproutcore/panes/picker.js +45 -0
  128. data/frameworks/sproutcore/tests/controllers/array.rhtml +86 -0
  129. data/frameworks/sproutcore/tests/controllers/controller.rhtml +273 -0
  130. data/frameworks/sproutcore/tests/controllers/object.rhtml +327 -0
  131. data/frameworks/sproutcore/tests/foundation/application.rhtml +125 -0
  132. data/frameworks/sproutcore/tests/foundation/array.rhtml +221 -0
  133. data/frameworks/sproutcore/tests/foundation/object.rhtml +69 -0
  134. data/frameworks/sproutcore/tests/globals/window.rhtml +45 -0
  135. data/frameworks/sproutcore/tests/panes/pane.rhtml +88 -0
  136. data/frameworks/sproutcore/tests/views/collection.rhtml +137 -0
  137. data/frameworks/sproutcore/tests/views/popup_button.rhtml +115 -0
  138. data/frameworks/sproutcore/tests/views/text_field.rhtml +37 -0
  139. data/frameworks/sproutcore/validators/credit_card.js +92 -0
  140. data/frameworks/sproutcore/validators/date.js +36 -0
  141. data/frameworks/sproutcore/validators/email.js +29 -0
  142. data/frameworks/sproutcore/validators/not_empty.js +24 -0
  143. data/frameworks/sproutcore/validators/number.js +55 -0
  144. data/frameworks/sproutcore/validators/password.js +78 -0
  145. data/frameworks/sproutcore/validators/validator.js +304 -0
  146. data/frameworks/sproutcore/views/button.js +425 -0
  147. data/frameworks/sproutcore/views/checkbox_field.js +30 -0
  148. data/frameworks/sproutcore/views/collection.js +1521 -0
  149. data/frameworks/sproutcore/views/container.js +62 -0
  150. data/frameworks/sproutcore/views/error_explanation.js +45 -0
  151. data/frameworks/sproutcore/views/field.js +214 -0
  152. data/frameworks/sproutcore/views/filter_button.js +29 -0
  153. data/frameworks/sproutcore/views/form.js +591 -0
  154. data/frameworks/sproutcore/views/image.js +141 -0
  155. data/frameworks/sproutcore/views/inline_text_editor.js +96 -0
  156. data/frameworks/sproutcore/views/label.js +176 -0
  157. data/frameworks/sproutcore/views/menu_item.js +90 -0
  158. data/frameworks/sproutcore/views/pagination.js +54 -0
  159. data/frameworks/sproutcore/views/popup_button.js +86 -0
  160. data/frameworks/sproutcore/views/popup_menu.js +137 -0
  161. data/frameworks/sproutcore/views/progress.js +100 -0
  162. data/frameworks/sproutcore/views/radio_field.js +107 -0
  163. data/frameworks/sproutcore/views/radio_group.js +48 -0
  164. data/frameworks/sproutcore/views/segmented.js +80 -0
  165. data/frameworks/sproutcore/views/select_field.js +272 -0
  166. data/frameworks/sproutcore/views/spinner.js +11 -0
  167. data/frameworks/sproutcore/views/tab.js +126 -0
  168. data/frameworks/sproutcore/views/text_field.js +179 -0
  169. data/frameworks/sproutcore/views/textarea_field.js +14 -0
  170. data/frameworks/sproutcore/views/toolbar.js +29 -0
  171. data/frameworks/sproutcore/views/view.js +1389 -0
  172. data/frameworks/sproutcore/views/workspace.js +170 -0
  173. data/generators/client/README +3 -0
  174. data/generators/client/USAGE +12 -0
  175. data/generators/client/client_generator.rb +53 -0
  176. data/generators/client/templates/core.js +19 -0
  177. data/generators/client/templates/english.lproj/body.css +0 -0
  178. data/generators/client/templates/english.lproj/body.rhtml +3 -0
  179. data/generators/client/templates/english.lproj/controls.css +0 -0
  180. data/generators/client/templates/english.lproj/strings.js +14 -0
  181. data/generators/client/templates/main.js +37 -0
  182. data/generators/controller/USAGE +16 -0
  183. data/generators/controller/controller_generator.rb +51 -0
  184. data/generators/controller/templates/controller.js +21 -0
  185. data/generators/controller/templates/test.rhtml +21 -0
  186. data/generators/framework/README +7 -0
  187. data/generators/framework/USAGE +12 -0
  188. data/generators/framework/framework_generator.rb +53 -0
  189. data/generators/framework/templates/core.js +20 -0
  190. data/generators/framework/templates/english.lproj/body.css +0 -0
  191. data/generators/framework/templates/english.lproj/body.rhtml +3 -0
  192. data/generators/framework/templates/english.lproj/controls.css +0 -0
  193. data/generators/framework/templates/english.lproj/strings.js +14 -0
  194. data/generators/language/USAGE +16 -0
  195. data/generators/language/language_generator.rb +47 -0
  196. data/generators/language/templates/strings.js +10 -0
  197. data/generators/model/USAGE +24 -0
  198. data/generators/model/model_generator.rb +55 -0
  199. data/generators/model/templates/fixture.js +11 -0
  200. data/generators/model/templates/model.js +20 -0
  201. data/generators/model/templates/test.rhtml +21 -0
  202. data/generators/test/USAGE +16 -0
  203. data/generators/test/templates/test.rhtml +21 -0
  204. data/generators/test/test_generator.rb +47 -0
  205. data/generators/view/USAGE +16 -0
  206. data/generators/view/templates/test.rhtml +21 -0
  207. data/generators/view/templates/view.js +20 -0
  208. data/generators/view/view_generator.rb +51 -0
  209. data/jsdoc/README.txt +119 -0
  210. data/jsdoc/app/DocFile.js +137 -0
  211. data/jsdoc/app/DocTag.js +110 -0
  212. data/jsdoc/app/Doclet.js +63 -0
  213. data/jsdoc/app/Dumper.js +143 -0
  214. data/jsdoc/app/JsDoc.js +103 -0
  215. data/jsdoc/app/JsHilite.js +45 -0
  216. data/jsdoc/app/JsIO.js +163 -0
  217. data/jsdoc/app/JsParse.js +385 -0
  218. data/jsdoc/app/JsPlate.js +130 -0
  219. data/jsdoc/app/JsTestrun.js +129 -0
  220. data/jsdoc/app/JsToke.js +564 -0
  221. data/jsdoc/app/Symbol.js +298 -0
  222. data/jsdoc/app/Transformer.js +14 -0
  223. data/jsdoc/app/Util.js +97 -0
  224. data/jsdoc/app/js.jar +0 -0
  225. data/jsdoc/app/run.js +144 -0
  226. data/jsdoc/plugins/min.js +316 -0
  227. data/jsdoc/plugins/strip.js +20 -0
  228. data/jsdoc/templates/sproutcore/class.tmpl +438 -0
  229. data/jsdoc/templates/sproutcore/default.css +241 -0
  230. data/jsdoc/templates/sproutcore/index.html +13 -0
  231. data/jsdoc/templates/sproutcore/index.tmpl +21 -0
  232. data/jsdoc/templates/sproutcore/prototype.js +4186 -0
  233. data/jsdoc/templates/sproutcore/publish.js +236 -0
  234. data/jsdoc/templates/sproutcore/splash.html +7 -0
  235. data/lib/sproutcore/build_tools/html_builder.rb +88 -0
  236. data/lib/sproutcore/build_tools/resource_builder.rb +194 -0
  237. data/lib/sproutcore/build_tools.rb +44 -0
  238. data/lib/sproutcore/bundle.rb +517 -0
  239. data/lib/sproutcore/bundle_manifest.rb +397 -0
  240. data/lib/sproutcore/generator_helper.rb +170 -0
  241. data/lib/sproutcore/helpers/capture_helper.rb +42 -0
  242. data/lib/sproutcore/helpers/static_helper.rb +80 -0
  243. data/lib/sproutcore/helpers/tag_helper.rb +110 -0
  244. data/lib/sproutcore/helpers/text_helper.rb +336 -0
  245. data/lib/sproutcore/helpers.rb +3 -0
  246. data/lib/sproutcore/jsdoc.rb +40 -0
  247. data/lib/sproutcore/jsmin.rb +247 -0
  248. data/lib/sproutcore/library.rb +258 -0
  249. data/lib/sproutcore/merb/bundle_controller.rb +179 -0
  250. data/lib/sproutcore/merb/router.rb +43 -0
  251. data/lib/sproutcore/merb.rb +27 -0
  252. data/lib/sproutcore/version.rb +9 -0
  253. data/lib/sproutcore/view_helpers/button_views.rb +302 -0
  254. data/lib/sproutcore/view_helpers/core_views.rb +284 -0
  255. data/lib/sproutcore/view_helpers/form_views.rb +258 -0
  256. data/lib/sproutcore/view_helpers/menu_views.rb +94 -0
  257. data/lib/sproutcore/view_helpers.rb +628 -0
  258. data/lib/sproutcore.rb +30 -0
  259. data/script/destroy +14 -0
  260. data/script/generate +14 -0
  261. data/script/txt2html +74 -0
  262. data/setup.rb +1585 -0
  263. data/spec/spec.opts +1 -0
  264. data/spec/spec_helper.rb +7 -0
  265. data/spec/sproutcore_spec.rb +11 -0
  266. data/tasks/deployment.rake +34 -0
  267. data/tasks/environment.rake +7 -0
  268. data/tasks/rspec.rake +21 -0
  269. data/tasks/website.rake +17 -0
  270. metadata +365 -0
@@ -0,0 +1,182 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('views/view') ;
7
+ require('views/container') ;
8
+
9
+ /**
10
+ @class Manages the panels on a page.
11
+
12
+ To make a view into a panel, just set the isPanel property on it. To
13
+ customize how panels are shown in your application, override the showPanel()
14
+ and hidePanel() methods.
15
+
16
+ @extends SC.View
17
+ */
18
+ SC.PanelView = SC.View.extend(
19
+ /** @scope SC.PanelView.prototype */
20
+ {
21
+
22
+ emptyElement: '<div id="panels" class="panels"><div class="overlay"></div></div>',
23
+
24
+ // Override this property to incldue an example view all panels
25
+ // will be wrapped in. The view must have a 'content' property that will
26
+ // be set to the view to show.
27
+ wrapperView: SC.ContainerView.extend({
28
+ emptyElement: '<div class="panel"><div class="root"></div><div class="top-left-edge"></div><div class="top-edge"></div><div class="top-right-edge"></div><div class="right-edge"></div><div class="bottom-right-edge"></div><div class="bottom-edge"></div><div class="bottom-left-edge"></div><div class="left-edge"></div></div>',
29
+
30
+ outlets: ['rootView'],
31
+ rootView: SC.View.outletFor('.root?')
32
+ }),
33
+
34
+ // this is filled with instances of the the wrapperView so we don't have
35
+ // to recreate them all the time.
36
+ _wrapperPool: null,
37
+
38
+ // this is used to get a new wrapper.
39
+ _getWrapperView: function() {
40
+ var ret = this._wrapperPool.pop() ;
41
+ if (ret) return ret ;
42
+ ret = this.wrapperView.viewFor() ;
43
+
44
+ if (ret.visibleAnimation) {
45
+ var va = Object.clone(ret.visibleAnimation) ;
46
+ va.onComplete = this.hidePanelDidComplete.bind(this) ;
47
+ ret.visibleAnimation = va ;
48
+ }
49
+
50
+ return ret ;
51
+ },
52
+
53
+ // ...................................
54
+ // SHOWING AND HIDING VIEWS
55
+ //
56
+
57
+ locationFor: function(view,evt) {
58
+ return { top: '50px', left: 'auto' } ;
59
+ },
60
+
61
+ // this is the method called by the view to show itself as a popup.
62
+ showPanel: function(view,evt) {
63
+ var wrapperView = this._getWrapperView() ;
64
+
65
+ // setup popupView.
66
+ wrapperView.set('animateVisible',false) ;
67
+ wrapperView.set('isVisible',false) ;
68
+ wrapperView.set('content',view) ; // set the popup view.
69
+ wrapperView.setClassName('standard-panel', !(view.get('hasCustomPanelWrapper') || false));
70
+ view._wrapperView = wrapperView ;
71
+
72
+ // The dimensions of the panel cannot be computed until it is actually
73
+ // added to the document. Turn off animation and add view with visiblity
74
+ // set to hidden so we can get dimensions.
75
+ this.nowShowing.push(view) ;
76
+ this.appendChild(wrapperView) ;
77
+ this.set('isVisible',true) ; // show panels
78
+
79
+ wrapperView.setStyle({ visibility: 'hidden' }) ;
80
+ wrapperView.set('isVisible',true) ; // show the panel
81
+
82
+ var dim = Element.getDimensions(view.rootElement) ;
83
+ wrapperView.setStyle(this.locationFor(view,evt)) ;
84
+
85
+ wrapperView.set('isVisible',false) ;
86
+ wrapperView.setStyle({ width: dim.width+'px', visibility: 'visible' });
87
+
88
+ wrapperView.set('animateVisible',true);
89
+ wrapperView.set('isVisible',true) ;
90
+ },
91
+
92
+ hidePanel: function(view) {
93
+ var didHideWrapperView = null ;
94
+
95
+ // clear view
96
+ if (view._wrapperView) {
97
+ if (view._wrapperView.visibleAnimation) {
98
+ } else {
99
+ didHideWrapperView = view._wrapperView ;
100
+ }
101
+ view._wrapperView.set('isVisible',false) ;
102
+ view._wrapperView = null ;
103
+ }
104
+
105
+ // now remove from list of popups and hide pane (maybe)
106
+ this.nowShowing = this.nowShowing.without(view) ;
107
+ if (didHideWrapperView) this.hidePanelDidComplete(didHideWrapperView) ;
108
+ },
109
+
110
+ hidePanelDidComplete: function(wrapperView) {
111
+ if (wrapperView.get('isVisible') != false) return ;
112
+ if (wrapperView) {
113
+ wrapperView.set('content',null) ;
114
+ this._wrapperPool.push(wrapperView) ;
115
+ }
116
+ if (this.nowShowing.length <= 0) this.set('isVisible',false);
117
+ },
118
+
119
+ init: function() {
120
+ arguments.callee.base.call(this) ;
121
+ this.nowShowing = [] ;
122
+ this._wrapperPool = [] ;
123
+ },
124
+
125
+ // ...................................
126
+ // SHOWING AND HIDING THE POPUP PANEL
127
+ //
128
+
129
+ panelStyle: {
130
+ zIndex: '10000',
131
+ visibility: 'visible',
132
+ position: 'absolute',
133
+ top: '0',
134
+ left: '0',
135
+ width: '100%',
136
+ height: '100%',
137
+ overflow: 'hidden'
138
+ },
139
+
140
+ showView: function() {
141
+
142
+ // add panel to body node if it has not been added already.
143
+ var bodyNode = $tag('body');
144
+ if (this.rootElement.parentNode != bodyNode) bodyNode.appendChild(this.rootElement) ;
145
+ this.setStyle(this.panelStyle) ;
146
+ if (!SC.isIE7() && bodyNode) Element.addClassName(bodyNode, 'under-panel') ;
147
+ },
148
+
149
+ hideView: function() {
150
+ var bodyNode = $tag('body');
151
+ this.setStyle({ zIndex: '-10000', visibility: 'hidden' }) ;
152
+ if (!SC.isIE7() && bodyNode) Element.removeClassName(bodyNode, 'under-panel') ;
153
+ },
154
+
155
+ // if the user clicks outside the top popup, then dismiss the popup unless
156
+ // it is modal.
157
+ didClick: function(ev) {
158
+ if (this.nowShowing.length == 0) return ; // nothing to do.
159
+
160
+ // find the top-most popup
161
+ var topPanel = this.nowShowing[this.nowShowing.length-1] ;
162
+ var tgt = Event.element(ev) ;
163
+ var tgtView = $view(tgt) ;
164
+
165
+ var view = topPanel._wrapperView ;
166
+ while(tgt && (tgt != this.rootElement) && (tgtView != view)) {
167
+ tgt = tgt.parentNode ;
168
+ tgtView = (tgt) ? $view(tgt) : null ;
169
+ }
170
+
171
+ // may dismiss if clicked outside of topPopup and isModal == false
172
+ if ((tgtView != view) && (!topPanel.get('isModal'))) {
173
+ topPanel.set('isVisible',false) ;
174
+ }
175
+ }
176
+
177
+ }) ;
178
+
179
+ SC.callOnLoad(function() {
180
+ if (!SC.page) SC.page = SC.Page.create() ;
181
+ SC.page.panels = SC.PanelView.outletFor(null);
182
+ }) ;
@@ -0,0 +1,60 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('views/view') ;
7
+ require('views/container') ;
8
+ require('globals/panels') ;
9
+
10
+ // This singleton manages the popups on the page. It will show an element
11
+ // called 'popups', which is appended to the end of the body node. To show
12
+ // a view as a popup, just call the popup() method on it along with an event.
13
+ // The view will be shown at the location more appropriate for the event.
14
+ // You can choose whether the popup is modal by setting the isModal property
15
+ // on the view.
16
+ SC.PopupView = SC.PanelView.extend({
17
+
18
+ emptyElement: '<div id="popups" class="popups"></div>',
19
+
20
+ wrapperView: SC.ContainerView.extend({
21
+ emptyElement: '<div class="popup"></div>',
22
+ visibleAnimation: {
23
+ visible: 'opacity: 1.0',
24
+ hidden: 'opacity: 0.0',
25
+ duration: 200,
26
+ onComplete: function(wrapperView) {
27
+ if (!wrapperView.get('isVisible')) {
28
+ SC.popups.hidePanelDidComplete(wrapperView) ;
29
+ }
30
+ }
31
+ }
32
+ }),
33
+
34
+ locationFor: function(view,ev) {
35
+ var x = (ev) ? (Event.pointerX(ev) - 20) : 100 ;
36
+ var y = (ev) ? Event.pointerY(ev) : 100 ;
37
+ var dim = view.get('size') ;
38
+ var screenSize = Element.getDimensions(this) ;
39
+
40
+ // fit on screen
41
+ var shift = (x+dim.width+50) - screenSize.width ;
42
+ if (shift>0) x -= shift ;
43
+ var shift = (y+dim.height+20) - screenSize.height ;
44
+ if (shift>0) y -= shift ;
45
+
46
+ return { left: x+'px', top: y+'px' };
47
+ },
48
+
49
+ // ...................................
50
+ // VIEW SUPPORT FUNCTION
51
+ //
52
+ // called in the context of the view.
53
+ viewHide: function() { SC.page.get('popups').hidePanel(this); }
54
+
55
+ }) ;
56
+
57
+ SC.callOnLoad(function() {
58
+ if (!SC.page) SC.page = SC.Page.create() ;
59
+ SC.page.popups = SC.PopupView.outletFor(null);
60
+ }) ;
@@ -0,0 +1,381 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('Core') ;
7
+ require('foundation/responder');
8
+ require('panes/pane');
9
+
10
+ // The window global object is automatically setup for each window that you
11
+ // load. Window listens for mouse and keyboard events and routes them to the
12
+ // first responder. Using the firstResponder method you can control who gets
13
+ // to respond to keyboard events.
14
+ SC.window = SC.PaneView.extend({
15
+
16
+ // This finds the first view responding to the event.
17
+ firstViewForEvent: function(evt) {
18
+ var el = Event.element(evt) ;
19
+ while(el && (el != document) && (!el._configured)) el = el.parentNode ;
20
+ if (el) el = SC.View.findViewForElement(el) ;
21
+ if (el == this) el = null ;
22
+ return el ;
23
+ },
24
+
25
+ // ........................................................................
26
+ // Window Size/Resizing
27
+ //
28
+
29
+ frame: function() {
30
+ var size = this.get('size') ;
31
+ return { x: 0, y: 0, width: size.width, height: size.height } ;
32
+ }.property('size'),
33
+
34
+ // this returns the size of the window, possibly reading it from the browser
35
+ // if needed.
36
+ size: function() {
37
+ if (!this._size) {
38
+ if (window.innerHeight) {
39
+ this._size = {
40
+ width: window.innerWidth,
41
+ height: window.innerHeight
42
+ };
43
+ } else if (document.documentElement && document.documentElement.clientHeight) {
44
+ this._size = {
45
+ width: document.documentElement.clientWidth,
46
+ height: document.documentElement.clientHeight
47
+ };
48
+ } else if (document.body) {
49
+ this._size = {
50
+ width: document.body.clientWidth,
51
+ height: document.body.clientHeight
52
+ };
53
+ }
54
+ }
55
+
56
+ return this._size ;
57
+ }.property(),
58
+
59
+ autoresizesChildViews: true,
60
+
61
+ _onresize: function(evt) {
62
+ var oldSize = Object.clone(this.get('size')) ;
63
+ this._size = null ;
64
+ var newSize = this.get('size') ;
65
+ if ((newSize.width != oldSize.width) || (newSize.height != oldSize.height)) {
66
+ this.resizeChildrenWithOldSize(oldSize) ;
67
+ }
68
+ },
69
+
70
+ // ........................................................................
71
+ // Keyboard Handling
72
+ //
73
+
74
+ _lastModifiers: null,
75
+ _handleModifierChanges: function(evt)
76
+ {
77
+ //console.debug('_lastModifiers: %o', this._lastModifiers);
78
+ // if the modifier keys have changed, then notify the first responder.
79
+ var m = this._lastModifiers = this._lastModifiers || { alt: false, ctrl: false, shift: false };
80
+
81
+ var changed = false;
82
+ if (evt.altKey != m.alt) { m.alt = evt.altKey; changed=true; }
83
+ if (evt.ctrlKey != m.ctrl) { m.ctrl = evt.ctrlKey; changed=true; }
84
+ if (evt.shiftKey != m.shift) { m.shift = evt.shiftKey; changed=true;}
85
+
86
+ if (changed)
87
+ {
88
+ evt._type = 'flagsChanged';
89
+ evt._modifiers = m;
90
+ SC.app.sendEvent( evt );
91
+ }
92
+ },
93
+
94
+ // this one gets called once when the key is down. We use this to handle
95
+ // function and non-printable keys. (i.e. if a modifier key is pressed or
96
+ // we can map to some non-printable set of keycodes.)
97
+ _onkeydown: function(evt)
98
+ {
99
+ // modifier keys are handled separately by the 'flagsChanged' event
100
+ this._handleModifierChanges(evt);
101
+ if (this._isModifierKey(evt)) return;
102
+ if (!this._isFunctionOrNonPrintableKey(evt)) return true; // let normal browser processing do its thing.
103
+ return this._sendEvent('keyDown', evt);
104
+ },
105
+
106
+ // this one gets used for all the other keys not handled by key down.
107
+ _onkeypress: function(evt)
108
+ {
109
+ if (this._isFunctionOrNonPrintableKey(evt)) return; // handled in _onkeydown
110
+ if (evt.charCode != undefined && evt.charCode == 0) return;
111
+ return this._sendEvent('keyDown', evt);
112
+ },
113
+
114
+ _onkeyup: function(evt)
115
+ {
116
+ // modifier keys are handled separately by the 'flagsChanged' event
117
+ this._handleModifierChanges(evt);
118
+ if (this._isModifierKey(evt)) return;
119
+ return this._sendEvent('keyUp', evt);
120
+ },
121
+
122
+ _sendEvent: function( sctype, evt )
123
+ {
124
+ evt._type = sctype;
125
+ evt._stopWhenHandled = (evt._stopWhenHandled !== undefined) ? evt._stopWhenHandled : true;
126
+
127
+ var handler = SC.app.sendEvent( evt );
128
+
129
+ if (handler && evt._stopWhenHandled) {
130
+ Event.stop(evt);
131
+ return false;
132
+ } else {
133
+ return true;
134
+ }
135
+ },
136
+
137
+ // util code factored out of keypress and keydown handlers
138
+ _isFunctionOrNonPrintableKey: function( evt )
139
+ {
140
+ return !!(evt.altKey || evt.ctrlKey || SC.FUNCTION_KEYS[evt.keyCode]);
141
+ },
142
+ _isModifierKey: function( evt )
143
+ {
144
+ return !!SC.MODIFIER_KEYS[evt.keyCode];
145
+ },
146
+
147
+
148
+
149
+ // ........................................................................
150
+ // Mouse Handling
151
+ //
152
+ // Mouse clicks are routed to the target view.
153
+ //
154
+ _mouseDownView: null,
155
+ _clickCount: 0,
156
+ _lastMouseUpAt: null,
157
+
158
+ dragDidStart: function(drag) {
159
+ this._mouseDownView = drag ;
160
+ },
161
+
162
+ _onmousedown: function(evt)
163
+ {
164
+ // first, save the click count. Click count resets if your down is
165
+ // more than 125msec after you last click up.
166
+ this._clickCount = this._clickCount + 1 ;
167
+ if (!this._lastMouseUpAt || ((Date.now() - this._lastMouseUpAt) > 200)) {
168
+ this._clickCount = 1 ;
169
+ }
170
+ evt.clickCount = this._clickCount ;
171
+
172
+ evt._type = 'mouseDown';
173
+ evt._stopWhenHandled = (evt._stopWhenHandled !== undefined) ? evt._stopWhenHandled : true;
174
+
175
+ this._mouseDownView = SC.app.sendEvent( evt );
176
+ if (this._mouseDownView && evt._stopWhenHandled)
177
+ {
178
+ Event.stop(evt);
179
+ }
180
+
181
+ // find the view to handle the mouseDown. go up the chain till you find
182
+ // one that implements didMouseDown or mouseDown && returns true.
183
+ /* var view = this.firstViewForEvent(evt) ;
184
+ var handled = false ;
185
+ while(view && (view != this) && !handled) {
186
+ var func = view.mouseDown || view.didMouseDown;
187
+ if (func) handled = func.call(view, evt) ;
188
+
189
+ if (!handled) view = view.get('nextResponder');
190
+ }
191
+ if (view == this) view = null;
192
+ this._mouseDownView = view ;
193
+
194
+ if (handled) Event.stop(evt) ;
195
+ */
196
+ },
197
+
198
+ // mouseUp only gets delivered to the view that handled the mouseDown evt.
199
+ // we also handle click and double click notifications through here to
200
+ // ensure consistant delivery. Note that if mouseDownView is not
201
+ // implemented, then no mouseUp event will be sent, but a click will be
202
+ // send.
203
+ _onmouseup: function(evt)
204
+ {
205
+ var handler = null;
206
+
207
+ this._lastMouseUpAt = Date.now();
208
+
209
+ // record click count.
210
+ evt.clickCount = this._clickCount ;
211
+
212
+ // attempt the mouseup call only if there's a target.
213
+ // don't want a mouseup going to anyone unless they handled the mousedown...
214
+ if (this._mouseDownView)
215
+ {
216
+ evt._type = 'mouseUp';
217
+ handler = SC.app.sendEvent(evt, this._mouseDownView);
218
+ }
219
+ // no one handled the mouseup... try doubleclick...
220
+ if (!handler && (this._clickCount == 2))
221
+ {
222
+ evt._type = 'doubleClick';
223
+ handler = SC.app.sendEvent(evt, this._mouseDownView);
224
+ }
225
+ // no one handled the doubleclick... try click...
226
+ if (!handler)
227
+ {
228
+ evt._type = 'click';
229
+ handler = SC.app.sendEvent(evt, this._mouseDownView);
230
+ }
231
+
232
+ this._mouseDownView = null;
233
+ },
234
+
235
+ _lastHovered: null,
236
+
237
+ // this will sent mouseOver, mouseOut, and mouseMoved to the views you
238
+ // hover over. To receive these events, you must implement the method.
239
+ // If any subviews implement them and return true, then you won't receive
240
+ // any notices.
241
+ //
242
+ // if there is a target mouseDown view, then mouse moved events will also
243
+ // trigger calls to mouseDragged.
244
+ //
245
+ _onmousemove: function(evt) {
246
+ var lh = this._lastHovered || [] ;
247
+ var nh = [] ;
248
+ var view = this.firstViewForEvent(evt) ;
249
+
250
+ // work up the view chain. Notify of mouse entered and
251
+ // mouseMoved if implemented.
252
+ while(view && (view != this)) {
253
+ var entered = view.mouseOver || view.didMouseOver || view.mouseEntered;
254
+ var moved = view.mouseMoved || view.mouseDidMove ;
255
+
256
+ if (lh.include(view)) {
257
+ if (moved) moved.call(view,evt) ;
258
+ nh.push(view) ;
259
+ } else {
260
+ if (entered) entered.call(view,evt) ;
261
+ nh.push(view) ;
262
+ }
263
+
264
+ view = view.get('nextResponder');
265
+ }
266
+
267
+ // now find those views last hovered over that were no longer found
268
+ // in this chain and notify of mouseExited.
269
+ for(var loc=0; loc < lh.length; loc++) {
270
+ view = lh[loc] ;
271
+ var exited = view.mouseOut || view.didMouseOut || view.mouseExited ;
272
+ if (exited && !nh.include(view)) exited.call(view, evt) ;
273
+ }
274
+
275
+ this._lastHovered = nh;
276
+
277
+ // also, if a mouseDownView exists, call the mouseDragged action, if it
278
+ // exists.
279
+ if (this._mouseDownView && this._mouseDownView.mouseDragged) {
280
+ this._mouseDownView.mouseDragged(evt) ;
281
+ }
282
+ },
283
+
284
+ // remove event observers.
285
+ _onunload: function() {
286
+ this._listenerCache.each(function(e){
287
+ Event.stopObserving.apply(Event, e) ;
288
+ });
289
+ },
290
+
291
+ _EVTS: ['mousedown', 'mouseup', 'click', 'dblclick', 'keydown', 'keyup', 'keypress', 'mouseover', 'mouseout', 'mousemove', 'resize', 'unload'],
292
+
293
+ _listenerCache: [],
294
+
295
+ setup: function() {
296
+ console.log('setup') ;
297
+
298
+ // setup event listeners for window.
299
+ var win = this ;
300
+ win._EVTS.each(function(e) {
301
+ var func = win['_on' + e] ;
302
+ var target = (SC.isIE() && (e != 'resize')) ? document : window ;
303
+ if (func) {
304
+ var f = func.bindAsEventListener(win) ;
305
+ Event.observe(target, e, f) ;
306
+ win._listenerCache.push([target, e, f]) ;
307
+ }
308
+ });
309
+
310
+ this.get('size') ; // fetch the size from the window and save it.
311
+ }
312
+ }).viewFor($tag('body')) ;
313
+
314
+
315
+ // events:
316
+ // window.onfocus --
317
+ // notify all views that they now have window focus.
318
+
319
+ // window.onblur --
320
+ // notify all views that they no longer have window focus.
321
+
322
+ // element.onfocus/element.onblur --
323
+ // when a field gains focus, it should become first responder. Other
324
+ // elements should become first responder when you click on them.
325
+
326
+ // window.onresize --
327
+ // call the resize code on the views to tell them their parent views resized.
328
+ // -- we should have a root view that is the window.
329
+
330
+ // window.onscroll --
331
+ // call the scroll code on the root view.
332
+
333
+ // element.onscroll --
334
+ // call the scroll code on the element.
335
+
336
+ // window.onunload --
337
+ // call this on all views? to let them unload....
338
+
339
+ // document.onclick --
340
+ // document.ondblclick --
341
+ // these events are ignored (actually, they are eaten) by the window object.
342
+ // click and double click events are handled by the mouseUp handler so that
343
+ // we can avoid calling click if mouseUp is handled by someone.
344
+
345
+ // document.onmousedown --
346
+ // document.onmouseup --
347
+ // find the target element and work your way up the DOM hierarchy until you
348
+ // find Views to handle the click.
349
+
350
+ // document.onmousemove --
351
+ // document.onmouseover --
352
+ // document.onmouseout --
353
+ // use these events to simulate mouseover and mouseout on views. Find the
354
+ // target element and work you way up the hierarchy until you find a view
355
+ // that responds to these events.
356
+ //
357
+ // also we should have some generic handlers in the window object that you
358
+ // can use to be notified when the mouse enters and leaves the window in
359
+ // general.
360
+
361
+ // formelement.onchange
362
+ // use to trigger a value change on the form field element.
363
+
364
+ // form.onreset
365
+ // um, do nothing? button will handle action directly.
366
+
367
+ // form.onsubmit
368
+ // disable so that AJAX code can takeover.
369
+
370
+ // document.onkeydown --
371
+ // document.onkeypress --
372
+ // document.onkeyup --
373
+ // notify the firstResponder and work up the chain until someone handles the
374
+ // keypress. You can have a defaultResponder, which gets the keypress if
375
+ // no one else does. First normalize key info.
376
+
377
+ // img.onerror --
378
+ // this should call some handler function in the ImageView.
379
+
380
+
381
+
@@ -0,0 +1,66 @@
1
+ <% # SPROUTCORE DEFAULT INDEX TEMPLATE
2
+ # This template provide provides a basic wrapper for a SproutCore client.
3
+ # Most of the time, it will be sufficient for your own needs. However, if
4
+ # you need to create your own template, you can do so by copying this file
5
+ # into your client, naming it 'index.rhtml' and then adding the options
6
+ # :index => 'index' to your client declaration in routes.rb.
7
+ #
8
+ # See the comments in this file for more information on what you can
9
+ # change.
10
+ -%>
11
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
12
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
13
+ <html>
14
+ <head>
15
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
16
+ <% # @title will be defined if you passed :title in routes.rb -%>
17
+ <title><%= (@title.to_s || bundle_name.to_s || '').capitalize %></title>
18
+ <% #
19
+ # This line should appear in your head area to include the stylesheets
20
+ # generated by your client. If you need to include your own
21
+ # stylesheets, you don't need to change it here. Instead, use the
22
+ # :requires option in routes.rb.
23
+ -%>
24
+ <%= stylesheets_for_client %>
25
+ </head>
26
+ <body class="<%= @theme || 'sc-theme' %>">
27
+ <% #
28
+ # This is where you root body element will appear. To cause your
29
+ # content to appear here, just declare content_for('body') in one of
30
+ # your partials.
31
+ -%>
32
+ <!-- Main Page Body -->
33
+ <%= @content_for_body %>
34
+
35
+ <% #
36
+ # This is where the resources you delcare will appear. You must
37
+ # include the following three lines verbatim for the resources you
38
+ # declare to be properly used.
39
+ -%>
40
+ <!-- Resources to be removed from DOM on page load -->
41
+ <div id="resources" style="display:none; visibility: hidden;">
42
+ <%= @content_for_resources -%>
43
+ </div>
44
+
45
+ <% #
46
+ # This line should appear at the bottom of your page to include your
47
+ # generated JavaScript and any libraries you reference. If you need
48
+ # to include other javascripts, add them to the :requires option of
49
+ # your client in routes.rb instead of changing it here.
50
+ -%>
51
+ <!-- Include Site Javascript -->
52
+ <%= javascripts_for_client %>
53
+
54
+ <% #
55
+ # The following lines to the closing body tag must be included at the
56
+ # very end of your file. This will actually setup the JavaScript
57
+ # views on your page and register SproutCore to start on page load.
58
+ -%>
59
+ <!-- Render Page Views -->
60
+ <%= render_page_views %>
61
+
62
+ <!-- Start SproutCore on Page Load -->
63
+ <script type="text/javascript">window.onload = SC.didLoad;</script>
64
+ <%= @content_for_final %>
65
+ </body>
66
+ </html>