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,43 @@
1
+ require 'sproutcore/merb/bundle_controller'
2
+
3
+ module SproutCore
4
+ module Merb
5
+ module RouterMethods
6
+
7
+ # Connect a BundleController to the specified location. All requests matching
8
+ # this path root will by default be handled by this new controller.
9
+ #
10
+ # ==== Params
11
+ # path<String>:: The root path or other matcher to use for the matcher. This
12
+ # will be passed through to the router, so you can use anything you like.
13
+ #
14
+ # === Options
15
+ # library:: Optional path to the library that should be hosted
16
+ # You can also include any other options that are known to Merb::Bundle
17
+ #
18
+ def connect_clients(match_path, opts ={}, &block)
19
+
20
+ # Create library
21
+ library_root = opts.delete(:library) || opts.delete(:library_root) || ::Merb.root
22
+ library = Library.library_for(library_root, opts)
23
+
24
+ # Define new subclass of bundle controller
25
+ cnt = 0
26
+ while Object.const_defined?(class_name = "SproutCoreBundleController#{cnt}".to_sym)
27
+ cnt += 1
28
+ end
29
+ klass = eval("class ::#{class_name} < SproutCore::Merb::BundleController; end; #{class_name}")
30
+
31
+ # Register library for class in BundleController
32
+ ::SproutCore::Merb::BundleController.register_library_for_class(library, klass)
33
+
34
+ # Finally, register match
35
+ return self.match(%r[^#{match_path}\/?.*]).to(:controller => "sprout_core_bundle_controller_#{cnt}", :action => 'main')
36
+
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ # Install in router.
43
+ Merb::Router::Behavior.send(:include, SproutCore::Merb::RouterMethods)
@@ -0,0 +1,27 @@
1
+ # This module defines the SproutCore support for Merb applications. To host a SproutCore
2
+ # app in your Merb application, simply add the following line to your router:
3
+ #
4
+ # Merb::Router.prepare do |r|
5
+ # r.connect_clients('/', LIBRARY_ROOT)
6
+ # end
7
+ #
8
+ # The first parameter you pass is the URL you want SproutCore apps to be served from. Anything
9
+ # URL beginning with this root will be automatically directed to the SproutCore build tools.
10
+ #
11
+ # The second parameter is an optional root path to the Library that you want hosted at that
12
+ # location. If you do not pass this parameter then Merb.root will be used (which is what you
13
+ # usually want anyway.)
14
+ #
15
+
16
+ # Load Merb if it is available
17
+ begin
18
+ require('merb-core')
19
+ rescue LoadError
20
+ end
21
+
22
+ # Load SproutCore Merb support if Merb meets minimum criteria
23
+ if defined?(Merb) && defined?(Merb::VERSION) && (Merb::VERSION.to_f >= 0.9)
24
+ Dir.glob(File.join(File.dirname(__FILE__),'merb','**','*.rb')).each { |x| require(x) }
25
+ else
26
+ puts "WARNING: sproutcore/merb required Merb 0.9.1 or later. Module was not loaded."
27
+ end
@@ -0,0 +1,9 @@
1
+ module SproutCore #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 9
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,302 @@
1
+ ############################################################
2
+ # BUTTON VIEW HELPERS
3
+ #
4
+ # You can do a lot of different things with buttons: push buttons, switches,
5
+ # checkboxes, radio buttons and more. This file contains the helpers you can
6
+ # use to help you build these.
7
+ #
8
+
9
+ require 'sproutcore/view_helpers/core_views'
10
+
11
+ module SproutCore
12
+ module ViewHelpers
13
+
14
+ # This is the core button_view helper. Most other helpers in this file
15
+ # descend from this helper. If a helper is not provided that already
16
+ # builds the button you want, you can probably use this helper to
17
+ # construct it yourself.
18
+ #
19
+ # :enabled (bindable) =>
20
+ # If set to true, the button will be enabled.
21
+ #
22
+ # :selected (bindable) =>
23
+ # Set to true, false or :mixed. This will determine if the button
24
+ # appears selected. You can bind to this option but more often you will
25
+ # want to bind to :value.
26
+ #
27
+ # :default (bindable) =>
28
+ # Set to true to make this button the default button triggered when
29
+ # you press return while focused in a panel or form.
30
+ #
31
+ # :cancel (bindable) =>
32
+ # Set to true to make this button the one triggered when you press
33
+ # return while focused on a panel or form.
34
+ #
35
+ # :theme => :regular | :back | :checkbox | :radio | :square |
36
+ # (your own theme)
37
+ # Use this to set the theme appearance of the button. The SC theme
38
+ # comes with built-in support for the ones listed above or you can
39
+ # name your own. a CSS class name will be assigned to the button with
40
+ # this theme name.
41
+ #
42
+ # :behavior => :push, :toggle, :on, :off
43
+ # Specify the behavior of the button when pressed. The default is
44
+ # :push.
45
+ #
46
+ # :tag =>
47
+ # The tag name to use for the button. Defaults to 'a'. If the tag is
48
+ # 'a', an href="javascript:;" will be added automatically unless you
49
+ # specify an alternate.
50
+ #
51
+ # :href =>
52
+ # optional href to pass. Generall you don't want to pass this.
53
+ #
54
+ # :label =>
55
+ # The value of the label placed inside the button. You can alternately
56
+ # specify inner_html which will be used a the label. Note that the
57
+ # button_view generator automatically wraps your inner_html with a
58
+ # standard button structure unless you pass :label => false
59
+ #
60
+ # :image =>
61
+ # Renders an image tag on the outside of the label span. If this is
62
+ # set, then the wrapping tag will also have 'image' css class applied.
63
+ #
64
+ # :sprite => [resource_url, x-ofset, y-offset]
65
+ # Render an image sprite! The expected size of the sprite depends on
66
+ # the class name of the view. If the x-offset or y-offset are numbers
67
+ # they will be converted to "px". If this is set, then the wrapping
68
+ # tag will also have 'sprite' css class applied.
69
+ #
70
+ # Alternatively, name the CSS class you want assigned to the img for
71
+ # the sprite.
72
+ #
73
+ view_helper :button_view do
74
+ # JavaScript
75
+ property :enabled, :key => 'isEnabled'
76
+
77
+ property :action
78
+ property :target
79
+
80
+ #property(:action) { |v| "function(ev) { return #{v}(this, ev); }" }
81
+ property :default, :key => 'isDefault'
82
+ property :cancel, :key => 'isCancel'
83
+ property :value
84
+ property :theme
85
+ property :size
86
+ property :behavior, :key => 'buttonBehavior'
87
+ property :toggle_on_value
88
+ property :toggle_off_value
89
+
90
+ property :key_equivalent, :key => :keyEquivalent
91
+
92
+
93
+ property(:selected, :key => 'isSelected') do |x|
94
+ (x == :mixed) ? 'SC.MIXED_STATE' : x
95
+ end
96
+
97
+ view 'SC.ButtonView'
98
+
99
+ # HTML
100
+ var :label, @inner_html || 'Submit'
101
+ var :tag, 'a'
102
+ var :theme, :regular
103
+ var :size, :normal
104
+
105
+ attribute(:href) { |x| (x.nil? && (@tag.downcase.to_s == 'a')) ? 'javascript:;' : nil }
106
+
107
+ # Add the theme to the CSS class.
108
+ css_class_names << 'button'
109
+ css_class_names << @theme unless @theme.nil? || @theme == false
110
+ css_class_names << @size unless @size.nil? || @size == false
111
+
112
+ var :image
113
+ var :sprite
114
+
115
+ if @image
116
+ @image = %(<img src="#{@image}" />)
117
+ css_class_names << 'image'
118
+
119
+ elsif @sprite
120
+ img_url = self.blank_url
121
+
122
+ if @sprite.instance_of?(Array)
123
+ xoff = @sprite[1]
124
+ xoff = "#{xoff}px" if xoff.kind_of?(Numeric)
125
+
126
+ yoff = @sprite[2]
127
+ yoff = "#{yoff}px" if yoff.kind_of?(Numeric)
128
+
129
+ # render image part
130
+ @image = %(<img class="sprite" style="background: url(#{@sprite[0]}) no-repeat #{xoff} #{yoff};" src="#{img_url}" />)
131
+
132
+ else
133
+ @image = %(<img class="#{@sprite} sprite" src="#{img_url}" />)
134
+ end
135
+
136
+ end
137
+
138
+ # Generate some standard HTML for unless :label => false.
139
+ unless @label == false
140
+ # Button Width properties must be set on the inner label. To deal
141
+ # with this remove any width style properties from the parent element
142
+ # and append them to the inner label.
143
+ @label_style = []
144
+ css_styles.flatten!
145
+ css_styles.reject! do | part |
146
+ if part =~ /width:/
147
+ @label_style << part
148
+ true
149
+ else
150
+ false
151
+ end
152
+ end
153
+ if @label_style.size > 0
154
+ @label_style = %(style="#{@label_style * ' '}" )
155
+ else
156
+ @label_style = ''
157
+ end
158
+
159
+ # Avoid doing the normal thing for anchor tags.
160
+ @inner_html = %(<span class="button-inner">#{@image}<span #{@label_style}class="label">#{@label}</span></span>)
161
+
162
+ else
163
+ @inner_html = [@image,@inner_html] * ''
164
+ end
165
+
166
+ end
167
+
168
+
169
+
170
+ view_helper :popup_button_view, :wraps => :button_view do
171
+ parent_helper
172
+ property :menu, :key => :menuName
173
+ view 'SC.PopupButtonView'
174
+ end
175
+
176
+
177
+
178
+ # Renders a back button
179
+ view_helper :back_button_view, :wraps => :button_view do
180
+ parent_helper :theme => :back
181
+ end
182
+
183
+ # Renders a checkbox. If you pass a label this will render the label
184
+ # text next to the checkbox. Unlike button_view, passing no :label is
185
+ # the same as passing :label => false.
186
+ view_helper :checkbox_view, :wraps => :button_view do
187
+ opts = { :theme => :checkbox }
188
+ opts[:label] = false if options[:label].nil?
189
+ parent_helper(opts)
190
+
191
+ # provide some defaults to the JavaScript.
192
+ property :behavior, :toggle, :key => 'buttonBehavior'
193
+
194
+ # render checkbox HTML.
195
+
196
+ img_url = self.blank_url
197
+ @inner_html = [%(<img class="button" src="#{img_url}" />)]
198
+ @inner_html << %(<span #{@label_style}class="label">#{@label}</span>) if @label
199
+ @inner_html = @inner_html.join ''
200
+ end
201
+
202
+ # Renders a radio buton. If you pass a label this will render the label
203
+ # text next to the checkbox. Unlike button_view, passing no :label is
204
+ # the same as passing :label => false.
205
+ view_helper :radio_view, :wraps => :button_view do
206
+ opts = { :theme => :radio }
207
+ opts[:label] = false if options[:label].nil?
208
+ parent_helper(opts)
209
+
210
+ # provide some defaults to the JavaScript.
211
+ property :behavior, :on, :key => 'buttonBehavior'
212
+
213
+ # render checkbox HTML.
214
+ img_url = self.blank_url
215
+ @inner_html = [%(<img class="button" src="#{img_url}" />)]
216
+ @inner_html << %(<span #{@label_style}class="label">#{@label}</span>) if @label
217
+ @inner_html = @inner_html.join ''
218
+ end
219
+
220
+
221
+ # This renders a group of radio buttons. The buttons are controlled by
222
+ # a RadioGroupView that will map the value to a set of selection states.
223
+ #
224
+ # :values => [REQ]
225
+ # Set this to the values you want displayed in the radio buttons. You
226
+ # can pass an array here of strings or symbols, in which case these will
227
+ # be used as the values for the buttons and the names will be created
228
+ # from them. Or you can pass an array of arrays. The first items is
229
+ # the key value, the second item is the human readable value.
230
+ # Alternatively, you can set the inner_html of your view to include
231
+ # radio buttons as outlets. In this case, you must name the outlets
232
+ # :key_button.
233
+ #
234
+ # :layout => :horizontal | :vertical
235
+ # This will write out horizontal or vertical to the CSS class names so
236
+ # you can control the layout of your radio buttons.
237
+ #
238
+ # :width =>
239
+ # This will set the width of each item in the view.
240
+ #
241
+ # BINDABLE OPTIONS
242
+ #
243
+ # :value =>
244
+ # The current value of the radio buttons.
245
+ #
246
+ view_helper :radio_group_view do
247
+
248
+ #JavaScript
249
+ property :value
250
+ view 'SC.RadioGroupView'
251
+
252
+ # HTML
253
+
254
+ # get the layout mode.
255
+ var :layout, :vertical
256
+ css_class_names << 'radio' # default class
257
+ css_class_names << @layout if @layout
258
+
259
+ var :tag, 'span'
260
+
261
+ # If a set of values was passed, build the button views automatically.
262
+ var :values
263
+ if @values
264
+ # Get the width styles out of the main style to put into the
265
+ # individual radio items.
266
+ css_styles.flatten!
267
+ @label_styles = css_styles.reject { |p| !(p =~ /width:/) }
268
+ css_styles.reject! { |p| @label_styles.include?(p) }
269
+
270
+ if @label_styles.size > 0
271
+ @label_styles = %( style="#{@label_styles * ' '}" )
272
+ else
273
+ @label_styles = ''
274
+ end
275
+
276
+ # save off client_builder. The context this is run in later will
277
+ # not retain the client_builder
278
+ current_client_builder = self.client_builder
279
+ html = @values.map do | v |
280
+ v = [v].flatten
281
+ key = v.first
282
+ label = (v.size > 1) ? v[1] : key.to_s.humanize
283
+ ViewHelpers::radio_view(:outlet => true, :label => label, :style => @label_styles, :toggle_on_value => key, :toggle_off_value => nil, :client => self.client_builder)
284
+ end
285
+
286
+ @inner_html = html * "\n"
287
+ end
288
+ end
289
+
290
+ # def self.blank_url
291
+ # cb = SproutCore::ClientBuilder.builder_for(:sproutcore)
292
+ # if cb
293
+ # img_url = cb.url_for('blank.gif')
294
+ # else
295
+ # # if the sproutcore client cannot be found, give it a shot anyway...
296
+ # img_url = '/static/sproutcore/en/blank.gif'
297
+ # end
298
+ # img_url
299
+ # end
300
+
301
+ end
302
+ end
@@ -0,0 +1,284 @@
1
+ ############################################################
2
+ # CORE VIEW HELPERS
3
+ # These view helpers create simple views based on the options
4
+ # you pass in. More complex components can be found in the
5
+ # view_kit.
6
+
7
+ module SproutCore
8
+ module ViewHelpers
9
+
10
+ # Render an SC.View. This is also the base for all other view helpers.
11
+ #
12
+ # :tag the wrapper tag. default: 'div'
13
+ # :class css class names. maybe a string or array.
14
+ # :panel if true, view will display as a panel. default: false
15
+ # :visible (bindable) if false, view will be hidden on page load.
16
+ # default: true
17
+ # :resize resize option. hash like this:
18
+ # { :left => :flexible, :right => :fixed, :width => :fixed }
19
+ #
20
+ view_helper :view do
21
+ var :inner_html
22
+ var :tag, 'div'
23
+ var :panel, false
24
+ var :animate
25
+ var :resize
26
+
27
+ # passing in :field is like passing in :outlet but it also adds a
28
+ # property called fieldType
29
+ var :field
30
+ if @field
31
+ @outlet = "#{@field.to_s}_field"
32
+ property :field_key, @field.to_s.camelize(:lower), :constant => true
33
+ end
34
+
35
+ attribute :title
36
+
37
+ # these are some standard CSS attributes you might want to support
38
+ bind :visible, :key => 'isVisible'
39
+ property :modal, :key => 'isModal'
40
+ property :custom_panel, :key => 'hasCustomPanelWrapper'
41
+ property :localize
42
+ property :validator
43
+ property :field_label
44
+
45
+ # set panel type
46
+ var :panel
47
+ var :dialog
48
+ var :picker
49
+ pane_def = (@panel) ? 'panel' : (@dialog ? 'dialog' : (@picker ? 'picker' : nil))
50
+ if pane_def.nil?
51
+ property :pane, :key => 'paneType'
52
+ else
53
+ property :pane, pane_def, :key => 'paneType'
54
+ end
55
+
56
+ # pass in a hash of properties and they will be added to the JS:
57
+ # :properties => { :prop_a => '1', :prop_b => '2' }
58
+ var :properties
59
+ if @properties
60
+ @properties.each { | k, v | property(k,v) { |b| b } }
61
+ end
62
+
63
+ if @animate
64
+ property :visible_animation, '', :constant => true do
65
+ key_map = { 'complete' => 'onComplete' }
66
+ animation_values = @animate.map do | k,v |
67
+ normalized_key = k.to_s.downcase
68
+ unless ['complete'].include?(normalized_key)
69
+ v = prepare_for_javascript(v)
70
+ end
71
+ k = key_map[normalized_key] || k
72
+ "#{k}: #{v}"
73
+ end
74
+ %({ #{ animation_values * ',' } })
75
+ end
76
+ end
77
+
78
+ # autoresize options.
79
+ if @resize
80
+ property :resize_options, '', :constant => true do
81
+ resize_values = []
82
+ @resize.each do |k,v|
83
+ case v
84
+ when :fixed
85
+ v = 'SC.FIXED'
86
+ when :flexible
87
+ v = 'SC.FLEXIBLE'
88
+ else
89
+ v = nil
90
+ end
91
+ resize_values << %(#{k}: #{v}) unless v.nil?
92
+ end
93
+ %({ #{resize_values * ',' } })
94
+ end
95
+ end
96
+
97
+ view('SC.View') { properties }
98
+
99
+ # deal with css classnames and styles.
100
+ # Note that you can append either arrays or single strings or symbols
101
+ # here. When the class names and styles are combined the ary will be
102
+ # flattened
103
+ var :class, :key => :class_names
104
+ css_class_names << @class_names if @class_names
105
+
106
+ var :style
107
+ css_styles << @style unless @style.nil?
108
+
109
+ # Standard CSS attributes you can pass as attributes to standard view helpers.
110
+ common_css_keys = [:width, :height, :min_height, :max_height, :min_width, :max_width]
111
+
112
+ common_css_keys.each do | key |
113
+ value = var key
114
+ if value
115
+ value = "#{value.to_i}px" if value.kind_of?(Numeric)
116
+ key = key.to_s.gsub('_','-')
117
+ css_styles << "#{key}: #{value};"
118
+ end
119
+ end
120
+
121
+ # render the basic content
122
+ content { (@tag == 'img') ? ot : %(#{ot}#{@inner_html}#{ct}) }
123
+
124
+ end
125
+
126
+ # Render an SC.LabelView. Inherits from SC.View
127
+ #
128
+ # :formatter Name of a formatter.
129
+ # :localize (bindable) localize string
130
+ # :escape_html (bindable) escapeHTML property
131
+ view_helper :label_view do
132
+ property(:formatter) { |v| v }
133
+ property :localize, false
134
+ property :escape_html, true, :key => 'escapeHTML'
135
+
136
+ var :label, nil
137
+ view 'SC.LabelView'
138
+
139
+ @inner_html = @label unless @label.nil?
140
+ end
141
+
142
+ # Render an SC.SpinnerView. Inherits from SC.View. You should bind
143
+ # :visible usually.
144
+ #
145
+ # :src Set the src of the spinner img. Defaults to
146
+ # "/images/spinner.gif"
147
+ view_helper :spinner_view do
148
+ var :form, false
149
+ var :src, '/images/spinner.gif'
150
+
151
+ view 'SC.SpinnerView'
152
+ if @form
153
+ bind(:visible, ".owner.isCommitting", :key => 'isVisible')
154
+ self.outlet = 'commitSpinner'
155
+ end
156
+
157
+ unless @inner_html
158
+ @inner_html = %(<img src="#{@src}" />)
159
+ end
160
+ attribute :class, 'spinner'
161
+
162
+ end
163
+
164
+ # Renders an SC.ProgressView. Includes the default HTML structure.
165
+ #
166
+ # :enabled (bindable) isEnabled property
167
+ # :indeterminate (bindable) isIndeterminate property
168
+ # :value (bindable) default value - float
169
+ # :maximum (bindable) maximum value - float
170
+ # :minimum (bindable) minimum value - float
171
+ view_helper :progress_view do
172
+ property :enabled, :key => 'isEnabled'
173
+ property :indeterminate, :key => 'isIndeterminate'
174
+ property :value
175
+ property :maximum
176
+ property :minimum
177
+ view 'SC.ProgressView'
178
+
179
+ attribute :class, 'progress outer'
180
+ unless @inner_html
181
+ @inner_html = <<EOF
182
+ <div class="outer-head"></div>
183
+ <div class="inner">
184
+ <div class="inner-head"></div>
185
+ <div class="inner-tail"></div>
186
+ </div>
187
+ <div class="outer-tail"></div>
188
+ EOF
189
+ end
190
+ end
191
+
192
+ view_helper :image_view do
193
+ view 'SC.ImageView'
194
+ property :content
195
+
196
+ var :tag, 'img'
197
+ end
198
+
199
+ view_helper :container_view do
200
+ view 'SC.ContainerView'
201
+ property :content
202
+ end
203
+
204
+ view_helper :segmented_view do
205
+ property :value
206
+ property :selection, :key => 'value'
207
+ property :enabled, :key => 'isEnabled'
208
+ property :allows_empty_selection
209
+
210
+ # :segments should contains an array of symbols or a hash of
211
+ # key => name pairs to be used to render the segment. Or you can
212
+ # just create your own button views.
213
+ var :segments
214
+ var :theme, 'regular'
215
+ if @segments
216
+ @segments = [@segments].flatten unless @segments.instance_of?(Array)
217
+ result = []
218
+ first = true
219
+ while seg = @segments.shift
220
+ class_names = [@theme,'segment']
221
+ class_names << ((first) ? 'segment-left' : ((@segments.size == 0) ? 'segment-right' : 'segment-inner'))
222
+ first = false
223
+
224
+ seg = [seg].flatten
225
+ key = seg.first || ''
226
+ label = seg.size > 1 ? seg.last : key.to_s.humanize.split.map { |x| x.capitalize }.join(' ')
227
+
228
+ result << ViewHelpers::button_view(:outlet => "#{key}_button", :label => label, :tag => 'a', :class => class_names )
229
+ end
230
+ @inner_html = result * ''
231
+ end
232
+
233
+ view 'SC.SegmentedView'
234
+ css_class_names << 'segments'
235
+
236
+ end
237
+
238
+ # Renders an SC.TabView. Name outlets you want flipped *_tab
239
+ # If you want, you can also pass a set of segments to be displayed
240
+ # above the tab view
241
+ view_helper :tab_view do
242
+ var :segments
243
+
244
+ property :now_showing
245
+ property :lazy_tabs
246
+
247
+ view 'SC.TabView'
248
+ css_class_names << "tab"
249
+
250
+ if @segments
251
+ # if this tab view has segments automatically attached, add class
252
+ # name.
253
+ css_class_names << 'segmented'
254
+ result = []
255
+ result << ViewHelpers::segmented_view(:outlet => :segmented_view, :segments => @segments, :bind => { :value => '*owner.nowShowing' })
256
+ result << ViewHelpers::view({:outlet => :root_view, :class => 'root'})
257
+ @inner_html = [(result * ""), %(<div style="display:none;">), (@inner_html || ''), %(</div>)] * ""
258
+ end
259
+
260
+ end
261
+
262
+
263
+ # inside the collection view you should do
264
+ # <%= view :prototype => :example_view %>
265
+ view_helper :collection_view do
266
+ property :content
267
+ property :selection
268
+ property :toggle, :key => 'useToggleSelection'
269
+ property :selectable, :key => 'isSelectable'
270
+ property :enabled, :key => 'isEnabled'
271
+ property :act_on_select
272
+ property(:example_view) { |v| v }
273
+ property(:example_group_view) { |v| v }
274
+
275
+ property(:group, :key => 'groupBy') do |v|
276
+ "['#{Array(v) * "','" }']"
277
+ end
278
+
279
+ property(:action) { |v| "function(ev) { return #{v}(this, ev); }" }
280
+ view 'SC.CollectionView'
281
+ end
282
+
283
+ end
284
+ end