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,115 @@
1
+ <% content_for('final') do %>
2
+ <script>
3
+
4
+
5
+ Test.context("A SC.PopupButtonView with no configured menu", {
6
+
7
+ "Should return null when asked for it's menu": function()
8
+ {
9
+ for (var i=0, n=this.buttons.length; i < n; i++)
10
+ {
11
+ (this.buttons[i].get('menu') == null).shouldEqual(true);
12
+ }
13
+ },
14
+ "Should return false if asked to trigger it's action": function()
15
+ {
16
+ for (var i=0, n=this.buttons.length; i < n; i++)
17
+ {
18
+ this.buttons[i].action().shouldEqual(false);
19
+ }
20
+ },
21
+ "Should not perform keyEquivalents": function()
22
+ {
23
+ for (var i=0, n=this.buttons.length; i < n; i++)
24
+ {
25
+ this.buttons[i].performKeyEquivalent('alt_shift_z').shouldEqual(false);
26
+ }
27
+ },
28
+ setup: function()
29
+ {
30
+ this.buttons = [
31
+ SC.PopupButtonView.viewFor(null),
32
+ SC.PopupButtonView.extend({ menuName: '' }).viewFor(null),
33
+ SC.PopupButtonView.extend({ menuName: 'foobarMenu' }).viewFor(null),
34
+ SC.PopupButtonView.extend({ menuName: false }).viewFor(null),
35
+ SC.PopupButtonView.extend({ menuName: null }).viewFor(null),
36
+ ];
37
+ },
38
+ teardown: function()
39
+ {
40
+ delete this.buttons;
41
+ }
42
+
43
+ });
44
+
45
+
46
+ Test.context("A SC.PopupButtonView with a properly configured menu", {
47
+
48
+ "Should return a menu of the correct type": function()
49
+ {
50
+ (this.button.get('menu') != null).shouldEqual(true);
51
+ this.button.get('menu').kindOf(SC.PopupMenuView).shouldEqual(true);
52
+ },
53
+ "Should return true if asked to trigger it's action": function()
54
+ {
55
+ this.button.action().shouldEqual(true);
56
+ },
57
+ "Should toggle the menu's visibility when triggering the action": function()
58
+ {
59
+ // for some reason this actually equals true... not sure why...
60
+ this.button.get('menu').get('isVisible').shouldEqual(false);
61
+ this.button.action();
62
+ this.button.get('menu').get('isVisible').shouldEqual(true);
63
+ this.button.action();
64
+ this.button.get('menu').get('isVisible').shouldEqual(false);
65
+ },
66
+ "Should have it's isSelected state bound to the menu's visibility": function()
67
+ {
68
+ // either by triggering the action...
69
+ this.button.get('isSelected').shouldEqual(false);
70
+ this.button.action();
71
+ this.button.get('isSelected').shouldEqual(true);
72
+ this.button.action();
73
+ this.button.get('isSelected').shouldEqual(false);
74
+ // or by showing/hiding the menu...
75
+ this.button.get('menu').set('isVisible', true);
76
+ this.button.get('isSelected').shouldEqual(true);
77
+ this.button.get('menu').set('isVisible', false);
78
+ this.button.get('isSelected').shouldEqual(false);
79
+ },
80
+ "Should send performKeyEquivalent messages to it's menu": function()
81
+ {
82
+ this.button.get('menu').performKeyEquivalent('alt_shift_z', {}).shouldEqual(true);
83
+ this.button.performKeyEquivalent('alt_shift_z', {}).shouldEqual(true);
84
+ },
85
+ "Should not send performKeyEquivalent messages to it's menu if disabled": function()
86
+ {
87
+ this.button.set('isEnabled', false);
88
+ this.button.performKeyEquivalent('alt_shift_z', {}).shouldEqual(false);
89
+ },
90
+ "Should not performKeyEquivalent for disabled menu items": function()
91
+ {
92
+ this.button.performKeyEquivalent('alt_shift_d', {}).shouldEqual(false);
93
+ },
94
+ setup: function()
95
+ {
96
+ this.menu = SC.PopupMenuView.extend({ paneType: "menu" }).create();
97
+ this.menu.appendChild( SC.MenuItemView.extend({ keyEquivalent: "alt_shift_z" }).create() );
98
+ this.menu.appendChild( SC.MenuItemView.extend({ keyEquivalent: "alt_shift_d", isEnabled: false }).create() );
99
+
100
+ this.button = SC.PopupButtonView.create();
101
+ this.button.set('menu', this.menu);
102
+ },
103
+ teardown: function()
104
+ {
105
+ delete this.menu;
106
+ delete this.button;
107
+ }
108
+
109
+ });
110
+
111
+
112
+
113
+
114
+ </script>
115
+ <% end %>
@@ -0,0 +1,37 @@
1
+ <% content_for('final') do %>
2
+ <script>
3
+
4
+ Test.context("A SC.TextFieldView", {
5
+
6
+ "Should allow text navigation keys when focused": function()
7
+ {
8
+ this.field.becomeFirstResponder();
9
+ this.field.get('isFirstResponder').shouldEqual(true);
10
+
11
+ var keynames = $w('backspace delete home end left right up down');
12
+ for (var i=0, n=keynames.length; i < n; i++)
13
+ {
14
+ var event = SC.Mock.KeyEvent.create({
15
+ type: 'keydown',
16
+ keyCode: SC.KEY_CODES[ keynames[i] ]
17
+ });
18
+ SC.window._onkeydown(event).shouldEqual(true);
19
+ event.stopped.shouldEqual(false);
20
+ }
21
+ },
22
+
23
+ setup: function()
24
+ {
25
+ this.field = SC.TextFieldView.create();
26
+ SC.window.appendChild(this.field);
27
+ },
28
+ teardown: function()
29
+ {
30
+ SC.window.removeChild(this.field);
31
+ delete this.field;
32
+ }
33
+
34
+ });
35
+
36
+ </script>
37
+ <% end %>
@@ -0,0 +1,92 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('validators/validator') ;
7
+
8
+ // Force to be a valid credit card number.
9
+ SC.Validator.CreditCard = SC.Validator.extend({
10
+
11
+ // expects a string of 16 digits. split into groups of 4
12
+ fieldValueForObject: function(object, form, field) {
13
+ if (typeof(object) == "string" && object.length == 16) {
14
+ object = [object.slice(0,4),object.slice(4,8),object.slice(8,12),object.slice(12,16)].join(' ') ;
15
+ }
16
+ return object ;
17
+ },
18
+
19
+ // remove all whitespace to make a single number.
20
+ objectForFieldValue: function(value, form, field) {
21
+ return value.replace(/^\s+|\s+$/g,'') ;
22
+ },
23
+
24
+ validate: function(form, field) {
25
+ return this.checkNumber(field.get('fieldValue')) ;
26
+ },
27
+
28
+ validateError: function(form, field) {
29
+ var label = field.get('errorLabel') || 'Field' ;
30
+ return $error("Invalid.CreditCard(%@)".loc(label), label);
31
+ },
32
+
33
+ // Borrowed from: David Leppek :: https://www.azcode.com/Mod10
34
+ checkNumber: function(ccNumb) {
35
+ var valid = "0123456789" // Valid digits in a credit card number
36
+ var len = ccNumb.length; // The length of the submitted cc number
37
+ var iCCN = parseInt(ccNumb); // integer of ccNumb
38
+ var sCCN = ccNumb.toString(); // string of ccNumb
39
+ sCCN = sCCN.replace (/^\s+|\s+$/g,''); // strip spaces
40
+ var iTotal = 0; // integer total set at zero
41
+ var bNum = true; // by default assume it is a number
42
+ var bResult = false; // by default assume it is NOT a valid cc
43
+ var temp; // temp variable for parsing string
44
+ var calc; // used for calculation of each digit
45
+
46
+ // Determine if the ccNumb is in fact all numbers
47
+ for (var j=0; j<len; j++) {
48
+ temp = "" + sCCN.substring(j, j+1);
49
+ if (valid.indexOf(temp) == "-1"){bNum = false;}
50
+ }
51
+
52
+ // if it is NOT a number, you can either alert to the fact,
53
+ // or just pass a failure
54
+ if(!bNum) bResult = false;
55
+
56
+ // Determine if it is the proper length
57
+ if((len == 0)&&(bResult)){ // nothing, field is blank AND passed above # check
58
+ bResult = false;
59
+ } else{ // ccNumb is a number and the proper length - let's see if it is a valid card number
60
+ if(len >= 15){ // 15 or 16 for Amex or V/MC
61
+ for(var i=len;i>0;i--){ // LOOP throught the digits of the card
62
+ calc = parseInt(iCCN) % 10; // right most digit
63
+ calc = parseInt(calc); // assure it is an integer
64
+ iTotal += calc; // running total of the card number as we loop - Do Nothing to first digit
65
+ i--; // decrement the count - move to the next digit in the card
66
+ iCCN = iCCN / 10; // subtracts right most digit from ccNumb
67
+ calc = parseInt(iCCN) % 10 ; // NEXT right most digit
68
+ calc = calc *2; // multiply the digit by two
69
+ // Instead of some screwy method of converting 16 to a string and then parsing 1 and 6 and then adding them to make 7,
70
+ // I use a simple switch statement to change the value of calc2 to 7 if 16 is the multiple.
71
+ switch(calc){
72
+ case 10: calc = 1; break; //5*2=10 & 1+0 = 1
73
+ case 12: calc = 3; break; //6*2=12 & 1+2 = 3
74
+ case 14: calc = 5; break; //7*2=14 & 1+4 = 5
75
+ case 16: calc = 7; break; //8*2=16 & 1+6 = 7
76
+ case 18: calc = 9; break; //9*2=18 & 1+8 = 9
77
+ default: calc = calc; //4*2= 8 & 8 = 8 -same for all lower numbers
78
+ }
79
+ iCCN = iCCN / 10; // subtracts right most digit from ccNum
80
+ iTotal += calc; // running total of the card number as we loop
81
+ } // END OF LOOP
82
+ if ((iTotal%10)==0){ // check to see if the sum Mod 10 is zero
83
+ bResult = true; // This IS (or could be) a valid credit card number.
84
+ } else {
85
+ bResult = false; // This could NOT be a valid credit card number
86
+ }
87
+ }
88
+ }
89
+ return bResult; // Return the results
90
+ }
91
+
92
+ }) ;
@@ -0,0 +1,36 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('validators/validator') ;
7
+
8
+ // Handle the parsing and display of dates.
9
+ SC.Validator.Date = SC.Validator.extend({
10
+
11
+ format: 'NNN d, yyyy h:mm:ss a',
12
+ naturalLanguage: true,
13
+
14
+ // if we have a number, then convert to a date object.
15
+ fieldValueForObject: function(object, form, field) {
16
+ var date ;
17
+ if (typeof(object) == "number") {
18
+ date = new Date(object) ;
19
+ } else if (object instanceof Date) { date = object; }
20
+
21
+ if (date) object = date.format(this.get('format'),this.get('naturalLanguage')) ;
22
+
23
+ return object ;
24
+ },
25
+
26
+ // try to pase value as a date. convert into a number, or return null if
27
+ // it could not be parsed.
28
+ objectForFieldValue: function(value, form, field) {
29
+ if (value) {
30
+ var date = Date.parseDate(value) ;
31
+ value = (date) ? date.getTime() : null ;
32
+ }
33
+ return value ;
34
+ }
35
+
36
+ }) ;
@@ -0,0 +1,29 @@
1
+ // ==========================================================================
2
+ // Email Validator
3
+ // Author: Charles Jolley
4
+ //
5
+ // Force a field to be an email address.
6
+ //
7
+ // ==========================================================================
8
+
9
+ require('validators/validator') ;
10
+ SC.Validator.Email = SC.Validator.extend({
11
+
12
+ validate: function(form, field) {
13
+ return (field.get('fieldValue') || '').match(/.+@.+\...+/) ;
14
+ },
15
+
16
+ validateError: function(form, field) {
17
+ var label = field.get('errorLabel') || 'Field' ;
18
+ return $error("Invalid.Email(%@)".loc(label), label) ;
19
+ }
20
+
21
+ }) ;
22
+
23
+ // this variant allows an email to be empty.
24
+ SC.Validator.EmailOrEmpty = SC.Validator.Email.extend({
25
+ validate: function(form, field) {
26
+ var value = field.get('fieldValue') ;
27
+ return (value && value.length > 0) ? value.match(/.+@.+\...+/) : true ;
28
+ }
29
+ }) ;
@@ -0,0 +1,24 @@
1
+ // ==========================================================================
2
+ // Not Empty Validator
3
+ // Author: Charles Jolley
4
+ //
5
+ // Force a field to be not empty.
6
+ //
7
+ // ==========================================================================
8
+
9
+ require('validators/validator') ;
10
+ SC.Validator.NotEmpty = SC.Validator.extend({
11
+
12
+ validate: function(form, field) {
13
+ var value = field.get('fieldValue');
14
+ var ret = !!value ;
15
+ if (ret && value.length) ret = value.length > 0 ;
16
+ return ret ;
17
+ },
18
+
19
+ validateError: function(form, field) {
20
+ var label = field.get('errorLabel') || 'Field' ;
21
+ return $error("Invalid.NotEmpty(%@)".loc(label.capitalize()), field.get('errorLabel'));
22
+ }
23
+
24
+ }) ;
@@ -0,0 +1,55 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2007 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('validators/validator') ;
7
+
8
+ // Handle the parsing and display of numbers.
9
+ SC.Validator.Number = SC.Validator.extend({
10
+
11
+ places: 0, // 0 to force int. otherwise fixed.
12
+
13
+ fieldValueForObject: function(object, form, field) {
14
+ switch($type(object)) {
15
+ case T_NUMBER:
16
+ object = object.toFixed(this.get('places')) ;
17
+ break ;
18
+ case T_NULL:
19
+ case T_UNDEFINED:
20
+ object = '';
21
+ break ;
22
+ }
23
+ return object ;
24
+ },
25
+
26
+ objectForFieldValue: function(value, form, field) {
27
+ switch($type(value)) {
28
+ case T_STRING:
29
+ if (value.length == '') {
30
+ value = null ;
31
+ } else if (this.get('places') > 0) {
32
+ value = parseFloat(value) ;
33
+ } else {
34
+ value = parseInt(value,0) ;
35
+ }
36
+ break ;
37
+ case T_NULL:
38
+ case T_UNDEFINED:
39
+ value = null ;
40
+ break ;
41
+ }
42
+ return value ;
43
+ },
44
+
45
+ validate: function(form, field) {
46
+ var value = field.get('fieldValue') ;
47
+ return (value == '') || !(isNaN(value) || isNaN(parseFloat(value))) ;
48
+ },
49
+
50
+ validateError: function(form, field) {
51
+ var label = field.get('errorLabel') || 'Field' ;
52
+ return $error("Invalid.Number(%@)".loc(label), label) ;
53
+ }
54
+
55
+ }) ;
@@ -0,0 +1,78 @@
1
+ // ==========================================================================
2
+ // Not Empty Validator
3
+ // Author: Charles Jolley
4
+ //
5
+ // This requires all password fields in the form to match. The normal
6
+ // validation only tries to match if all password fields are not empty.
7
+ // submit validation requires a match no matter what.
8
+ //
9
+ // ==========================================================================
10
+
11
+ require('validators/validator') ;
12
+ SC.Validator.Password = SC.Validator.extend({
13
+
14
+ attachTo: function(form,field) {
15
+ argments.callee.base.call(this,form,field) ;
16
+ if (!this.fields) this.fields = [] ;
17
+ this.fields.push(field) ;
18
+ },
19
+
20
+ validate: function(force) {
21
+ if (!this.fields || this.fields.length == 0) return true ;
22
+
23
+ var empty = false ;
24
+ var notEmpty = false ;
25
+ var ret = true ;
26
+ var value = this.fields[0].get('fieldValue') ;
27
+ this.fields.each(function(field) {
28
+ var curValue = field.get('fieldValue') ;
29
+ if (curValue != value) ret= false ;
30
+ if (!curValue || curValue.length == 0) empty = true ;
31
+ if (curValue && curValue.length > 0) notEmpty = true ;
32
+ }) ;
33
+
34
+ // if forces, valid OK if there was an empty. If not forced, valid OK
35
+ // only if all fields match AND they are not all empty.
36
+ if (force) {
37
+ return (notEmpty == false) ? false : ret ;
38
+ } else {
39
+ return (empty == true) ? true : ret ;
40
+ }
41
+ },
42
+
43
+ // update field states
44
+ updateFields: function(form,valid) {
45
+ if (!this.fields || this.fields.length == 0) return true ;
46
+ var err = "Invalid.Password".loc();
47
+ var topField = this._field ;
48
+ this.fields.each(function(f) {
49
+ var msg = (valid) ? null : ((f == topField) ? err : '') ;
50
+ form.setErrorFor(f,msg) ;
51
+ }) ;
52
+ return (valid) ? SC.Validator.OK : err ;
53
+ },
54
+
55
+ validateChange: function(form, field, oldValue) {
56
+ return this.updateFields(form, this.validate(false)) ;
57
+ },
58
+
59
+ // this method is called just before the form is submitted.
60
+ // field: the field toe validate.
61
+ validateSubmit: function(form, field) {
62
+ return this.updateFields(form, this.validate(true)) ;
63
+ },
64
+
65
+ // this method gets called 1ms after the user types a key (if a change is
66
+ // allowed). You can use this validate the new partial string and return
67
+ // an error if needed.
68
+ //
69
+ // The default will validate a partial only if there was already an error.
70
+ // this allows the user to try to get it right before you bug them.
71
+ validatePartial: function(form, field) {
72
+ var isInvalid = !this._field.get('isValid') ;
73
+ if (isInvalid) {
74
+ return this.updateFields(form, this.validate(false)) ;
75
+ } else return SC.Validator.NO_CHANGE ;
76
+ }
77
+
78
+ }) ;