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,304 @@
1
+ // ==========================================================================
2
+ // Validators
3
+ // Author: Charles Jolley
4
+ // ==========================================================================
5
+
6
+ //
7
+ // Validators provide a way for you to implement simple form field validation
8
+ // and transformation. To use a validator, simply name the validator in the
9
+ // "validate" attribute in your text field. For example, if you want to
10
+ // validate a field using the PhoneNumberValidator use this:
11
+ //
12
+ // <input value="1234567890" validate="phone-number" />
13
+ //
14
+ // Validators get notified at three points. You can implement one or all
15
+ // of these methods to support validation. All of the validate methods except
16
+ // for validateKeypress behave the same way. You are passed a form, field,
17
+ // and possibly the oldValue. You are expected to return Validator.OK or
18
+ // an error string. Inside this method you typically do one of all of the
19
+ // following:
20
+ //
21
+ // 1. You can simply validate the field value and return OK or an error str.
22
+ // 2. You can modify the field value (for example, you could format the
23
+ // string to match some predefined format).
24
+ // 3. If you need to roundtrip the server first to perform validation, you can
25
+ // return Validator.OK, then save the form and field info until after the
26
+ // roundtrip. On return, if there is a problem, first verify the field
27
+ // value has not changed and then call form.errorFor(field,str) ;
28
+ //
29
+ SC.Validator = SC.Object.extend({
30
+
31
+ // ..........................................
32
+ // OBJECT VALUE CONVERSION
33
+ //
34
+ // The following methods are used to convert the string value of a field
35
+ // to and from an object value. The default implementations return
36
+ // the string, but you can override this to provide specific behaviors.
37
+ // For example, you might add or remove a dollar sign or convert the
38
+ // value to a number.
39
+
40
+ // This method should return the value to set in the field for the passed
41
+ // object value. The form and field to be set MAY (but will not always)
42
+ // be passed also.
43
+ fieldValueForObject: function(object, form, field) { return object; },
44
+
45
+ // This method should return the object value for the string passed. The
46
+ // form and field the value came from MAY (but will not always) be passed
47
+ // also.
48
+ objectForFieldValue: function(value, form, field) { return value; },
49
+
50
+ // ..........................................
51
+ // VALIDATION PRIMITIVES
52
+ //
53
+ // You can implement standard behavior for your validator by using the
54
+ // vaidate and validateError methods. validate() should return false
55
+ // if the field is not valid.
56
+ //
57
+ // Expects:
58
+ // form: the form
59
+ // field: the field to validate
60
+ //
61
+ // Returns:
62
+ // true if the field is valid, otherwise not.
63
+ //
64
+ validate: function(form, field) { return true; },
65
+
66
+ // This is the other standard validator method that can be used to impement
67
+ // basic validation. This should return an error object explaining why
68
+ // the field is not valid. It will only be called if validate() returned
69
+ // false.
70
+ //
71
+ // Expects:
72
+ // form: the form
73
+ // field: the field that is no valid.
74
+ //
75
+ // Returns:
76
+ // Error string.
77
+ //
78
+ validateError: function(form, field) {
79
+ return $error(
80
+ "Invalid.General(%@)".loc(field.get('fieldValue')),
81
+ field.get('fieldKey')) ;
82
+ },
83
+
84
+ // ..........................................
85
+ // VALIDATION API
86
+ //
87
+
88
+ // this method gets invoked just before the user ends editing of the field.
89
+ //
90
+ // Expects;
91
+ // field: the field that was changed.
92
+ // oldValue: the value of the field before the user changed it.
93
+ //
94
+ // Return:
95
+ // SC.Validator.OK if the item was valid, an error object if the item is
96
+ // not valid.
97
+ //
98
+ validateChange: function(form, field, oldValue) {
99
+ return (this.validate(form,field)) ? SC.Validator.OK : this.validateError(form, field);
100
+ },
101
+
102
+ // this method is called for the field just before the form is submitted.
103
+ //
104
+ // Expects:
105
+ // form: the form the field belongs to
106
+ // field: the field to validate.
107
+ //
108
+ // Returns:
109
+ // An error string of SC.Validator.OK if the field is valid. If you return
110
+ // an error string, form submission will be cancelled.
111
+ //
112
+ validateSubmit: function(form, field) {
113
+ return (this.validate(form,field)) ? SC.Validator.OK : this.validateError(form, field);
114
+ },
115
+
116
+ // this method gets called 1ms after the user types a key (if a change is
117
+ // allowed). You can use this validate the new partial string and return
118
+ // an error if needed.
119
+ //
120
+ // The default will validate a partial only if there was already an error.
121
+ // this allows the user to try to get it right before you bug them.
122
+ //
123
+ // Expects:
124
+ // form: the form the field belongs to
125
+ // field: the field to validate.
126
+ //
127
+ // Returns:
128
+ // An error string if there was a problem, SC.Validator.OK if you checked
129
+ // the field and it was valid or SC.Validator.NO_CHANGE if you did not
130
+ // check the field. (Passing back OK will hide any showing errors.)
131
+ //
132
+ validatePartial: function(form, field) {
133
+ if (!field.get('isValid')) {
134
+ return (this.validate(form,field)) ? SC.Validator.OK : this.validateError(form, field);
135
+ } else return SC.Validator.NO_CHANGE ;
136
+ },
137
+
138
+ // this method gets called when the user types a key. It's useful to
139
+ // restrict the letters and numbers the user is allowed to enter. Return
140
+ // true/false to allow the keypress or not.
141
+ //
142
+ // Expects:
143
+ // form: the form the field belongs to
144
+ // field: the field in focus.
145
+ // char: a string with the characters being added.
146
+ //
147
+ // Returns:
148
+ // true to allow the keypress, false otherwise.
149
+ //
150
+ validateKeypress: function(form, field,charStr) { return true; },
151
+
152
+ // .....................................
153
+ // OTHER METHODS
154
+
155
+ // this method will be called on all validators when they are attached to
156
+ // a field. You can use this to do any setup that you need.
157
+ attachTo: function(form,field) {
158
+ // this._form = form ;
159
+ // this._field = field ;
160
+ // var that = this ;
161
+ // ['focus','change','blur','keypress'].each(function(key) {
162
+ // var f = that['_'+key].bindAsEventListener(that) ;
163
+ // Event.observe(field,key,f) ;
164
+ // }) ;
165
+ //
166
+ // if (!this._boundPartial) this._boundPartial = this._partial.bind(this) ;
167
+ // if (field.addObserver) field.addObserver('fieldValue',this._boundPartial);
168
+ // return this ;
169
+ },
170
+
171
+ // this method is called on a validator just before it is removed from a
172
+ // field. You can tear down any setup you did for the attachTo() method.
173
+ detachFrom: function(form, field) {
174
+
175
+ }
176
+
177
+ // detach: function() {
178
+ // var that = this ;
179
+ // ['focus','change','blur', 'keypress'].each(function(key) {
180
+ // var f = that['_'+key].bindAsEventListener(that) ;
181
+ // Event.stopObserving(that._field,key,f) ;
182
+ // }) ;
183
+ // if (this._field.removeObserver) {
184
+ // this._field.removeObserver('fieldValue',this._boundPartial) ;
185
+ // }
186
+ // return this ;
187
+ // },
188
+ //
189
+ // // save the old value before the user makes changes
190
+ // _focus: function(ev) {
191
+ // this._oldValue = this._field.get('fieldValue');
192
+ // },
193
+ //
194
+ // _blur: function(ev) {
195
+ // if (this._oldValue != this._field.get('fieldValue')) this._change(ev) ;
196
+ // this._oldValue = null ;
197
+ // },
198
+ //
199
+ // // invoked whenever the field value changes.
200
+ // _change: function(ev) {
201
+ // var err = this.validateChange(this._form,this._field,this._oldValue) ;
202
+ // this._oldValue = null ;
203
+ // if (err == SC.Validator.NO_CHANGE) return ; // nothing to do.
204
+ // if (err == SC.Validator.OK) err = null ;
205
+ // this._form.setErrorFor(this._field,err) ; // also clears error.
206
+ // },
207
+ //
208
+ // _keypress: function(ev) {
209
+ // var str = Event.getCharString(ev) ;
210
+ // var allow = this.validateKeypress(this._form,this._field,str) ;
211
+ // return allow ;
212
+ // },
213
+ //
214
+ // _partial: function() {
215
+ // var err = this.validatePartial(this._form,this._field) ;
216
+ // if (err == SC.Validator.NO_CHANGE) return ; // nothing to do
217
+ // if (err == SC.Validator.OK) err = null ;
218
+ // if (this._field.set) this._field.set('isValid', err == null)
219
+ // this._form.setErrorFor(this._field,err) ;
220
+ // },
221
+ //
222
+ // // invoked by form.
223
+ // _validate: function() {
224
+ // var err = this.validateSubmit(this._form,this._field) ;
225
+ // if (err == SC.Validator.NO_CHANGE) return true ; // nothing to do.
226
+ // if (err == SC.Validator.OK) err = null ;
227
+ // this._form.setErrorFor(this._field,err) ;
228
+ // return (err == null) ; // true = ok to submit.
229
+ // }
230
+
231
+ }) ;
232
+
233
+ SC.Validator.mixin({
234
+
235
+ // CONSTANTS
236
+ OK: true, NO_CHANGE: false,
237
+
238
+ // this is invoked by a field whenever a validator is attached to the field.
239
+ // The passed validatorKey can be a validator instance, a validator class
240
+ // or a string naming a validator. To make your validator
241
+ // visible, you should name your validator under the SC.Validator base.
242
+ // for example SC.Validator.Number would get used for the 'number'
243
+ // validator key.
244
+ //
245
+ // This understands validatorKey strings in the following format:
246
+ // * 'key' or 'multiple_words' will find validators Key and MultipleWords
247
+ // * if you want to share a single validator among multiple fields (for
248
+ // example to validate that two passwords are the same) set a name inside
249
+ // brackets. i.e. 'password[pwd]'.
250
+ //
251
+ findFor: function(form,field, validatorKey) {
252
+
253
+ // Convert the validator into a validator instance.
254
+ var validator ;
255
+ if (!validatorKey) return ; // nothing to do...
256
+
257
+ if (validatorKey instanceof SC.Validator) {
258
+ validator = validatorKey ;
259
+ } else if (validatorKey.isClass) {
260
+ validator = validatorKey.create() ;
261
+
262
+ } else if ($type(validatorKey) == T_STRING) {
263
+
264
+ // extract optional key name
265
+ var name = null ;
266
+ var m = validatorKey.match(/^(.+)\[(.*)\]/) ;
267
+ if (m) {
268
+ validatorKey = m[1] ; name = m[2];
269
+ }
270
+
271
+ // convert the validatorKey name into a class.
272
+ validatorKey = ('-' + validatorKey).camelize() ;
273
+ var validatorClass = SC.Validator[validatorKey] ;
274
+ if (validatorClass == null) {
275
+ throw "validator %@ not found for %@".fmt(validatorKey, field) ;
276
+ return null ;
277
+ } else if (name) {
278
+
279
+ // if a key was also passed, then find the validator in the list of
280
+ // validators for the form. Otherwise, just create a new instance.
281
+ if (!form) {
282
+ throw "named validator (%@) could not be found for field %@ because the field does not belong to a form".fmt(name,field) ;
283
+ return null ;
284
+ }
285
+
286
+ if (!form._validatorHash) form._validatorHash = {} ;
287
+ var validator = (name) ? form._validatorHash[name] : null ;
288
+ if (!validator) validator = validatorClass.create() ;
289
+ if (name) form._validatorHash[name] = validator ;
290
+ } else validator = validatorClass.create() ;
291
+ }
292
+
293
+ return validator ;
294
+ },
295
+
296
+ fieldValueForObject: function(object, form, field) {
297
+ return this.prototype.fieldValueForObject(object,form,field) ;
298
+ },
299
+
300
+ objectForFieldValue: function(value, form, field) {
301
+ return this.prototype.objectForFieldValue(value,form,field) ;
302
+ }
303
+
304
+ })