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,413 @@
1
+ // ==========================================================================
2
+ // SC.PathModule
3
+ // Author: Charles Jolley
4
+ //
5
+ // When creating a web app, you often need to find elements in your page to
6
+ // configure them on load. These elements are often marked with a class or
7
+ // id. General purpose methods such as $$() or getElementsByClassName are
8
+ // not very good for this because they search entire trees of nodes.
9
+ //
10
+ // These methods are much faster because they make some assumptions about
11
+ // how your elements are structured.
12
+ //
13
+ // ==========================================================================
14
+
15
+ require('Core') ;
16
+ require('foundation/benchmark') ;
17
+
18
+ // Constants
19
+ SC.BENCHMARK_SELECTOR = NO ;
20
+ NO_LIMIT = 10000 ;
21
+
22
+ // PathModule is high-performance API for locating DOM nodes in your HTML
23
+ // document. It's designed to be used by searching elements from a parent
24
+ // node.
25
+ //
26
+ // PathModule is patched into Prototypes Element.Methods, which means that
27
+ // you can automatically access this API for any DOM element retrieved via
28
+ // the $() operator. You can also mixin the PathModule api to your own
29
+ // objects. Be sure to also have a property called rootElement that points to
30
+ // the root DOM element you want to search.
31
+ //
32
+ SC.PathModule = {
33
+
34
+ $$func: function(func, levels, max, nest) {
35
+ return SC._PathModule.$$func(this.rootElement,func,levels,max,nest);
36
+ },
37
+
38
+ $$C: function(className, levels, max, nest) {
39
+ return SC._PathModule.$$C(this.rootElement,className,levels,max,nest);
40
+ },
41
+
42
+ $$T: function(tagName, levels, max, nest) {
43
+ return SC._PathModule.$$T(this.rootElement,tagName,levels,max,nest);
44
+ },
45
+
46
+ $$P: function(property, value, levels, max, nest) {
47
+ return SC._PathModule.$$P(this.rootElement, property, value, levels, max, nest);
48
+ },
49
+
50
+ $$S: function(selector, levels, max, nest) {
51
+ return SC._PathModule.$$S(this.rootElement, selector, levels, max, nest);
52
+ },
53
+
54
+ // finds the first node for which func returns true.
55
+ $func: function(func, levels) {
56
+ return SC._PathModule.$func(this.rootElement, func, levels);
57
+ },
58
+
59
+ // finds the first node with class name. returns element, not array.
60
+ $C: function(className, levels) {
61
+ return SC._PathModule.$C(this.rootElement, className, levels);
62
+ },
63
+
64
+ // finds the first node with tag name. returns element, not array.
65
+ $T: function(tagName, levels) {
66
+ return SC._PathModule.$T(this.rootElement, tagName, levels);
67
+ },
68
+
69
+ // find first node with an attribute matching then named value.
70
+ $P: function(attr, value, levels) {
71
+ return SC._PathModule.$P(this.rootElement, attr, value, levels);
72
+ },
73
+
74
+ // find first node matching the specified class selector.
75
+ $S: function(selector, levels) {
76
+ return SC._PathModule.$S(this.rootElement, selector, levels);
77
+ },
78
+
79
+ // find an element and configure it as the named view if it is not already
80
+ // configured.
81
+ $$view: function(selector, viewClass, levels, max, nest) {
82
+ return SC._PathModule.$$view(this.rootElement, selector, viewClass, levels, max, nest) ;
83
+ },
84
+
85
+ // find the first element matching the selector and create a view if it is
86
+ // not already configured.
87
+ $view: function(selector, viewClass, levels) {
88
+ return SC._PathModule.$view(this.rootElement, selector, viewClass, levels) ;
89
+ }
90
+
91
+ };
92
+
93
+ // This version of PathModule can be added to Element.Methods among others.
94
+ // It is the same API except that it passes the element as the first parameter.
95
+ SC._PathModule = {
96
+
97
+ // this is the core method that needs to be implemented for each object.
98
+ // this method will search the receiver (up to _levels_ deep) for _max_
99
+ // elements for which the function func() returns true.
100
+ //
101
+ // el: (req) the root element. If you pass null, document will be used.
102
+ // func: (req) the function to be used to check each element.
103
+ // levels: (opt) the max levels deep in nested elements. defaults: NO_LIMIT
104
+ // max: (opt) the maximum number of elements to return. defaults:
105
+ // NO_LIMIT
106
+ // nest: (opt) if true, then the children of matched elements will also be
107
+ // searched. if your element matches will never be nested, setting
108
+ // this to false can be much faster. defaults: false
109
+ $$func: function(el, func, levels, max, nest) {
110
+ // defaults
111
+ levels = levels || NO_LIMIT ; max = max || NO_LIMIT; nest = nest || false;
112
+
113
+ // function to search this node.
114
+ var searchNode = function(node, depth, remain, includeThisNode) {
115
+ var ret = [] ;
116
+
117
+ // does this node match?
118
+ // we extend any returned elements so you can chain these methods.
119
+ // on browsers that support HTMLElement.prototype, this will do nothing.
120
+ var match = (includeThisNode) ? func(node) : false ;
121
+ if (match) { ret.push(node); remain--; }
122
+
123
+ // can we search children?
124
+ depth-- ;
125
+ if ((match && !nest) || (remain<=0) || (depth<=0)) return ret;
126
+
127
+ // search children.
128
+ node = node.firstChild ;
129
+ while(node && (remain > 0)) {
130
+ var found = searchNode(node,depth,remain,true) ;
131
+ remain -= found.length ;
132
+ ret = ret.concat(found) ;
133
+ node = node.nextSibling ;
134
+ }
135
+ return ret ;
136
+ } ;
137
+
138
+ return searchNode(el || document, levels+1, max, false) ;
139
+ },
140
+
141
+ // finds all nodes with class name.
142
+ $$C: function(el, className, levels, max, nest) {
143
+ return SC._PathModule.$$func(el, function(node) {
144
+ return Element.hasClassName(node, className) ;
145
+ }, levels, max, nest) ;
146
+ },
147
+
148
+ // find all nodes with tag name
149
+ $$T: function(el, tagName, levels, max, nest) {
150
+ tagName = tagName.toUpperCase() ;
151
+ return SC._PathModule.$$func(el, function(node) {
152
+ return node.tagName == tagName;
153
+ }, levels, max, nest) ;
154
+ },
155
+
156
+ // find all nodes with an attribute matching then named value.
157
+ $$P: function(el, property, value, levels, max, nest) {
158
+ return SC._PathModule.$$func(el, function(node) {
159
+ var pvalue = (node.getAttribute) ? node.getAttribute(property) : node[property] ;
160
+ return pvalue == value;
161
+ }, levels, max, nest) ;
162
+ },
163
+
164
+ // this will parse the selector and then execute the selectors to return
165
+ // the result. this understands a very simple form for selectors. the
166
+ // parts are split by spaces. and treated like so:
167
+ // '.classname' = class name
168
+ // 'tag' = tag
169
+ // '#id' = an id. (this will bypass the normal selector methods)
170
+ // 'attr=value' = find an attr with the value.
171
+ //
172
+ // understands the following qualifiers:
173
+ // .selector:3 => find .selector at most 3 levels deep
174
+ // .selector:3:4 => find at most 4 .selectors at most 3 levels deep
175
+ // .selector? => find at most 1 .selector, any depth.
176
+ // .selector?3 => find at most 3 .selectors, any depth
177
+ // .selector:*:4 => find at more 4 .selectors at any depth.
178
+ //
179
+ // You can also directly access child nodes by doing:
180
+ // .selector[0][1][3] -> get child 3 of child 1 of child 0.
181
+ // or:
182
+ // [0][2][3] -> search base.
183
+ //
184
+ $$S: function(el,selector, levels, max, nest) {
185
+ var parts = selector.split(' ') ;
186
+ var ret = [el] ; var nextMax = null ; var bits ;
187
+ var blevels; var bmax; var q; var indicies ;
188
+
189
+ parts.each(function(part) {
190
+ // this is included for compatibility with earlier changes I made to
191
+ // prototype. the preferred way to do this in the future is with with
192
+ // the colon format.
193
+ if (part == '?') { nextMax = 1; return ; }
194
+
195
+ // get defaults
196
+ blevels = levels; bmax = (nextMax) ? nextMax : max ;
197
+ nextMax = null ;
198
+
199
+ // if there are indexes, find those and save them.
200
+ if (part.slice(part.length-1,part.length) == ']') {
201
+ bits = part.split('[') ;
202
+ part = bits.shift();
203
+ indicies = bits.map(function(b) {return parseInt(b.slice(0,-1),0);});
204
+ } else indicies = null ;
205
+
206
+ // find found modifiers
207
+ bits = part.split('?') ;
208
+ part = bits[0] ;
209
+ if (bits.length > 1) {
210
+ bmax = (bits[1].length == 0) ? 1 : parseInt(bits[1],0) ;
211
+ }
212
+
213
+ // find level modifiers
214
+ bits = part.split(':') ;
215
+ part = bits[0] ;
216
+ if (bits.length > 1) blevels = (bits[1] == '*') ? '*' : parseInt(bits[1],0) ;
217
+ if (bits.length > 2) bmax = (bits[2] == '*') ? '*' : parseInt(bits[2],0) ;
218
+
219
+ // convert star to NO_LIMIT
220
+ if (blevels == '*') blevels = NO_LIMIT ;
221
+ if (bmax == '*') bmac = NO_LIMIT ;
222
+
223
+ // prepare the selector info.
224
+ // q tells us how to process the first part.
225
+ // part is the first part of the selector
226
+ // bits are any extra css selectors.
227
+ if (part && part.length > 0) {
228
+ q = part.slice(0,1) ;
229
+ if (['.','#'].indexOf(q) >= 0) {
230
+ part = part.slice(1,part.length) ;
231
+ }
232
+
233
+ bits = part.split('.') ;
234
+ part = bits[0] ;
235
+ bits = bits.slice(1,bits.length) ;
236
+
237
+ // optimization for # types.
238
+ var fret = null ;
239
+ if (q == '#') {
240
+ fret = $(part) ;
241
+ fret = (fret) ? [fret] : null ;
242
+ if (fret) ret = fret ;
243
+ }
244
+
245
+ // otherwise pass this off to $$func to actually search.
246
+ if (fret == null) {
247
+ fret = [] ;
248
+ for(var i=0;i<ret.length;i++) {
249
+ var found = SC._PathModule.$$func(ret[i],function(node) {
250
+ var match ;
251
+ switch(q) {
252
+ case '.':
253
+ NODE = node ;
254
+ var elementClassName = node.className;
255
+ if (elementClassName && (elementClassName.length > 0)) {
256
+ match = (elementClassName == part ||
257
+ elementClassName.match( new RegExp("(^|\\s)" + part +
258
+ "(\\s|$)"))) ;
259
+ } else match = false ;
260
+ break ;
261
+ case '#':
262
+ match = node.id == part ;
263
+ break ;
264
+ default:
265
+ if (node.tagName) {
266
+ match = (node.tagName.toLowerCase() == part.toLowerCase()) ;
267
+ } else { match = false; }
268
+ }
269
+
270
+ // if the first item matched, verify that the others match as well.
271
+ for(var i=0; match && i < bits.length; i++) {
272
+ if (!Element.hasClassName(node,bits[i])) match = false ;
273
+ }
274
+ return match ;
275
+ }, blevels, bmax, nest) ;
276
+ fret = fret.concat(found) ;
277
+ }
278
+ ret = fret ;
279
+ }
280
+ } else if ($type(ret) != T_ARRAY) ret = [ret] ;
281
+
282
+ // now follow indicies, if there are any
283
+ if (indicies && indicies.length > 0 && ret) {
284
+ ret = ret.map(function(el){
285
+ for(var iloc=0; el && (iloc < indicies.length); iloc++) {
286
+ el = el.childNodes[indicies[iloc]] ;
287
+ }
288
+ return el;
289
+ }) ;
290
+ }
291
+ }) ;
292
+ return ret ;
293
+ },
294
+
295
+ // finds the first node for which func returns true.
296
+ $func: function(el,func, levels) {
297
+ var ret = SC._PathModule.$$func(el,func,levels,1,false) ;
298
+ return (ret.length>0) ? ret[0] : null ;
299
+ },
300
+
301
+ // finds the first node with class name. returns element, not array.
302
+ $C: function(el, className, levels) {
303
+ var ret = SC._PathModule.$$C(el, className,levels,1,false) ;
304
+ return (ret.length>0) ? ret[0] : null ;
305
+ },
306
+
307
+ // finds the first node with tag name. returns element, not array.
308
+ $T: function(el, tagName, levels) {
309
+ var ret = SC._PathModule.$$T(el, tagName,levels,1,false) ;
310
+ return (ret.length>0) ? ret[0] : null ;
311
+ },
312
+
313
+ // find first node with an attribute matching then named value.
314
+ $P: function(el, attr, value, levels) {
315
+ var ret = SC._PathModule.$$A(el, attr, value,levels,1,false) ;
316
+ return (ret.length>0) ? ret[0] : null ;
317
+ },
318
+
319
+ // find first node matching the specified class selector.
320
+ $S: function(el, selector, levels) {
321
+ var ret = SC._PathModule.$$S(el, selector,levels,1,false) ;
322
+ return (ret.length>0) ? ret[0] : null ;
323
+ },
324
+
325
+ // find an element and configure it as the named view if it is not already
326
+ // configured.
327
+ $$view: function(el, selector, viewClass, levels, max, nest) {
328
+ //if (!viewClass) viewClass = SC.View;
329
+ var ret ;
330
+ if (selector && (typeof(selector) != 'string')) {
331
+ ret = [selector] ;
332
+ } else {
333
+ ret = SC._PathModule.$$S(el,selector,levels,max,nest) ;
334
+ }
335
+ if (ret) ret = ret.map(function(x) { return (viewClass) ? viewClass.viewFor(x) : SC.View.findViewForElement(x); }) ;
336
+ return ret ;
337
+ },
338
+
339
+ // find the first element matching the selector and create a view if it is
340
+ // not already configured.
341
+ $view: function(el, selector, viewClass, levels) {
342
+ var ret = SC._PathModule.$$view(el, selector, viewClass, levels, 1, false) ;
343
+ return (ret.length>0) ? ret[0] : null ;
344
+ }
345
+
346
+ } ;
347
+
348
+ // Install benchmark report for selector if configured.
349
+ if (SC.BENCHMARK_SELECTOR) {
350
+ ['$$S','$$C','$$T','$S','$C','$T'].each(function(mname) {
351
+ SC.Benchmark.install(SC._PathModule,mname) ;
352
+ }) ;
353
+ SC.Benchmark.install(window,'$$$') ;
354
+ }
355
+
356
+ // longer form aliases of the functions.
357
+ Object.extend(SC._PathModule, {
358
+ $$class: SC._PathModule.$$C,
359
+ $$tag: SC._PathModule.$$T,
360
+ $$sel: SC._PathModule.$$S,
361
+ $$prop: SC._PathModule.$$P,
362
+
363
+ $class: SC._PathModule.$C,
364
+ $tag: SC._PathModule.$T,
365
+ $sel: SC._PathModule.$S,
366
+ $prop: SC._PathModule.$P
367
+ }) ;
368
+
369
+ // longer form aliases of the functions.
370
+ Object.extend(SC.PathModule, {
371
+ $$class: SC.PathModule.$$C,
372
+ $$tag: SC.PathModule.$$T,
373
+ $$sel: SC.PathModule.$$S,
374
+ $$prop: SC.PathModule.$$P,
375
+
376
+ $class: SC.PathModule.$C,
377
+ $tag: SC.PathModule.$T,
378
+ $sel: SC.PathModule.$S,
379
+ $prop: SC.PathModule.$P
380
+ }) ;
381
+
382
+ // Add _PathModule to the appropriate elements. Add to Element.Methods which
383
+ // will cause it to be copied onto elements automatically in IE when you
384
+ // call IE.
385
+ Object.extend(Element.Methods,SC._PathModule) ;
386
+ Object.extend(Element,SC._PathModule) ;
387
+
388
+ // applies to Element.
389
+ if (typeof HTMLElement != 'undefined') {
390
+ Object.extend(HTMLElement.prototype,SC.PathModule) ;
391
+ }
392
+
393
+ // applies to document
394
+ Object.extend(document,SC.PathModule) ;
395
+ document.rootElement = document ;
396
+
397
+ // applies to window.
398
+ Object.extend(Object.extend(window,SC.PathModule), {
399
+ $$func: function(func, levels, max, nest) {
400
+ return document.$$func(func,levels,max,nest) ;
401
+ }
402
+ });
403
+
404
+ // applies to arrays. Note the override of $$func to act on the group.
405
+ Object.extend(Object.extend(Array.prototype,SC.PathModule), {
406
+ $$func: function(func, levels, max, nest) {
407
+ var ret = [] ;
408
+ for(var loc=0;loc<this.length;loc++) {
409
+ ret = ret.concat(this[loc].$$func(func,levels,max,nest)) ;
410
+ }
411
+ return ret ;
412
+ }
413
+ }) ;