sproutcore 1.0.1003 → 1.0.1008

Sign up to get free protection for your applications and to get access to all the features.
Files changed (276) hide show
  1. data/Buildfile +15 -3
  2. data/Rakefile +3 -7
  3. data/VERSION.yml +2 -2
  4. data/buildtasks/manifest.rake +2 -0
  5. data/frameworks/sproutcore/Buildfile +2 -0
  6. data/frameworks/sproutcore/HISTORY +218 -203
  7. data/frameworks/sproutcore/README +47 -6
  8. data/frameworks/sproutcore/apps/tests/english.lproj/main_page.css +4 -0
  9. data/frameworks/sproutcore/design/Design Charts.graffle +2945 -4332
  10. data/frameworks/sproutcore/frameworks/bootstrap/README +9 -0
  11. data/frameworks/sproutcore/frameworks/bootstrap/core.js +7 -0
  12. data/frameworks/sproutcore/frameworks/bootstrap/setup_body_class_names.js +10 -0
  13. data/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +28 -0
  14. data/frameworks/sproutcore/frameworks/bootstrap/system/loader.js +45 -0
  15. data/frameworks/sproutcore/frameworks/datastore/models/many_attribute.js +9 -8
  16. data/frameworks/sproutcore/frameworks/datastore/models/record.js +49 -9
  17. data/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +9 -0
  18. data/frameworks/sproutcore/frameworks/datastore/models/single_attribute.js +3 -2
  19. data/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +81 -8
  20. data/frameworks/sproutcore/frameworks/datastore/system/query.js +26 -5
  21. data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +47 -0
  22. data/frameworks/sproutcore/frameworks/datastore/system/store.js +164 -32
  23. data/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +32 -4
  24. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/error_methods.js +56 -0
  25. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/normalize.js +1 -1
  26. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/unknownProperty.js +15 -0
  27. data/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +16 -1
  28. data/frameworks/sproutcore/frameworks/datastore/tests/models/record_attribute.js +1 -1
  29. data/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +22 -1
  30. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/chain.js +32 -1
  31. data/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/core_methods.js +70 -0
  32. data/frameworks/sproutcore/frameworks/datastore/tests/system/query/evaluation.js +12 -0
  33. data/frameworks/sproutcore/frameworks/datastore/tests/system/record_array/error_methods.js +50 -0
  34. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitRecord.js +9 -9
  35. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/core_methods.js +8 -1
  36. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataHashDidChange.js +79 -0
  37. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataSourceCallbacks.js +24 -0
  38. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/error_methods.js +62 -0
  39. data/frameworks/sproutcore/frameworks/datastore/tests/system/store/init.js +2 -0
  40. data/frameworks/sproutcore/frameworks/debug/core.js +10 -6
  41. data/frameworks/sproutcore/frameworks/designer/controllers/page_design.js +43 -18
  42. data/frameworks/sproutcore/frameworks/designer/core.js +10 -0
  43. data/frameworks/sproutcore/frameworks/designer/english.lproj/selection_handles.css +58 -0
  44. data/frameworks/sproutcore/frameworks/designer/{views/mixins → mixins}/button.js +0 -0
  45. data/frameworks/sproutcore/frameworks/designer/views/{controls/button.js → button.js} +6 -2
  46. data/frameworks/sproutcore/frameworks/designer/views/designer.js +566 -136
  47. data/frameworks/sproutcore/frameworks/designer/views/selection_handles.js +77 -0
  48. data/frameworks/sproutcore/frameworks/desktop/core.js +12 -0
  49. data/frameworks/sproutcore/frameworks/desktop/english.lproj/alert.css +1 -1
  50. data/frameworks/sproutcore/frameworks/desktop/english.lproj/drag.css +3 -2
  51. data/frameworks/sproutcore/frameworks/desktop/english.lproj/list_item.css +0 -36
  52. data/frameworks/sproutcore/frameworks/desktop/english.lproj/menu.css +14 -0
  53. data/frameworks/sproutcore/frameworks/desktop/english.lproj/modal.css +4 -0
  54. data/frameworks/sproutcore/frameworks/desktop/english.lproj/slider.css +2 -0
  55. data/frameworks/sproutcore/frameworks/desktop/english.lproj/tab.css +0 -4
  56. data/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +8 -5
  57. data/frameworks/sproutcore/frameworks/desktop/panes/alert.js +2 -2
  58. data/frameworks/sproutcore/frameworks/desktop/panes/menu.js +100 -111
  59. data/frameworks/sproutcore/frameworks/desktop/panes/panel.js +1 -1
  60. data/frameworks/sproutcore/frameworks/desktop/panes/picker.js +51 -13
  61. data/frameworks/sproutcore/frameworks/desktop/panes/{drop_down.js → select_button.js} +70 -109
  62. data/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +8 -0
  63. data/frameworks/sproutcore/frameworks/desktop/system/root_responder.js +69 -23
  64. data/frameworks/sproutcore/frameworks/desktop/system/undo_manager.js +4 -4
  65. data/frameworks/sproutcore/frameworks/desktop/tests/panes/menu/methods.js +2 -0
  66. data/frameworks/sproutcore/frameworks/desktop/tests/panes/{dropDown → select_button}/methods.js +15 -11
  67. data/frameworks/sproutcore/frameworks/desktop/tests/panes/{dropDown → select_button}/ui.js +22 -22
  68. data/frameworks/sproutcore/frameworks/desktop/tests/views/button/methods.js +1 -1
  69. data/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/methods.js +0 -1
  70. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/deleteSelection.js +1 -1
  71. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/deselect.js +19 -3
  72. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/itemViewForContentIndex.js +1 -1
  73. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +53 -28
  74. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/select.js +6 -6
  75. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/selectNextItem.js +23 -9
  76. data/frameworks/sproutcore/frameworks/desktop/tests/views/collection/selectPreviousItem.js +24 -10
  77. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowHeightForContentIndex.js +1 -1
  78. data/frameworks/sproutcore/frameworks/desktop/tests/views/list/ui_row_heights.js +1 -1
  79. data/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +10 -3
  80. data/frameworks/sproutcore/frameworks/desktop/tests/views/radio/methods.js +1 -1
  81. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/ui.js +50 -28
  82. data/frameworks/sproutcore/frameworks/desktop/tests/views/scroller/methods.js +6 -6
  83. data/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +3 -3
  84. data/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +8 -8
  85. data/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +1 -1
  86. data/frameworks/sproutcore/frameworks/desktop/tests/views/tab/methods.js +1 -1
  87. data/frameworks/sproutcore/frameworks/desktop/views/button.js +5 -3
  88. data/frameworks/sproutcore/frameworks/desktop/views/checkbox.js +4 -3
  89. data/frameworks/sproutcore/frameworks/desktop/views/collection.js +125 -96
  90. data/frameworks/sproutcore/frameworks/desktop/views/grid.js +1 -0
  91. data/frameworks/sproutcore/frameworks/desktop/views/list.js +68 -18
  92. data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +134 -56
  93. data/frameworks/sproutcore/frameworks/desktop/views/menu_item.js +18 -11
  94. data/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +562 -2
  95. data/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +13 -0
  96. data/frameworks/sproutcore/frameworks/desktop/views/progress.js +11 -8
  97. data/frameworks/sproutcore/frameworks/desktop/views/radio.js +7 -7
  98. data/frameworks/sproutcore/frameworks/desktop/views/scroll.js +99 -33
  99. data/frameworks/sproutcore/frameworks/desktop/views/scroller.js +3 -7
  100. data/frameworks/sproutcore/frameworks/desktop/views/segmented.js +0 -7
  101. data/frameworks/sproutcore/frameworks/desktop/views/separator.js +2 -3
  102. data/frameworks/sproutcore/frameworks/desktop/views/slider.js +0 -8
  103. data/frameworks/sproutcore/frameworks/desktop/views/source_list_group.js +1 -1
  104. data/frameworks/sproutcore/frameworks/desktop/views/split.js +27 -7
  105. data/frameworks/sproutcore/frameworks/desktop/views/tab.js +2 -6
  106. data/frameworks/sproutcore/frameworks/foundation/controllers/array.js +15 -10
  107. data/frameworks/sproutcore/frameworks/foundation/controllers/tree.js +20 -1
  108. data/frameworks/sproutcore/frameworks/foundation/debug/control_test_pane.js +1 -1
  109. data/frameworks/sproutcore/frameworks/foundation/english.lproj/bootstrap.rhtml +3 -6
  110. data/frameworks/sproutcore/frameworks/foundation/english.lproj/button_view.css +3 -0
  111. data/frameworks/sproutcore/frameworks/foundation/english.lproj/core.css +8 -0
  112. data/frameworks/sproutcore/frameworks/foundation/english.lproj/inline_editor.css +12 -0
  113. data/frameworks/sproutcore/frameworks/foundation/english.lproj/label.css +11 -0
  114. data/frameworks/sproutcore/frameworks/foundation/english.lproj/text_field.css +13 -0
  115. data/frameworks/sproutcore/frameworks/foundation/mixins/button.js +1 -2
  116. data/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +70 -21
  117. data/frameworks/sproutcore/frameworks/foundation/mixins/selection_support.js +88 -54
  118. data/frameworks/sproutcore/frameworks/foundation/mixins/static_layout.js +0 -25
  119. data/frameworks/sproutcore/frameworks/foundation/mixins/string.js +23 -2
  120. data/frameworks/sproutcore/frameworks/foundation/panes/pane.js +34 -23
  121. data/frameworks/sproutcore/frameworks/foundation/private/tree_item_observer.js +20 -0
  122. data/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +32 -23
  123. data/frameworks/sproutcore/frameworks/foundation/system/browser.js +2 -2
  124. data/frameworks/sproutcore/frameworks/foundation/system/bundle.js +77 -15
  125. data/frameworks/sproutcore/frameworks/foundation/system/core_query.js +5 -4
  126. data/frameworks/sproutcore/frameworks/foundation/system/cursor.js +1 -1
  127. data/frameworks/sproutcore/frameworks/foundation/system/render_context.js +22 -7
  128. data/frameworks/sproutcore/frameworks/foundation/system/request.js +466 -309
  129. data/frameworks/sproutcore/frameworks/foundation/system/responder.js +2 -1
  130. data/frameworks/sproutcore/frameworks/foundation/system/response.js +457 -0
  131. data/frameworks/sproutcore/frameworks/foundation/system/root_responder.js +66 -15
  132. data/frameworks/sproutcore/frameworks/foundation/system/routes.js +4 -4
  133. data/frameworks/sproutcore/frameworks/foundation/system/timer.js +6 -4
  134. data/frameworks/sproutcore/frameworks/foundation/system/utils.js +46 -8
  135. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/array_case.js +17 -0
  136. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/enum_case.js +18 -5
  137. data/frameworks/sproutcore/frameworks/foundation/tests/controllers/array/null_case.js +1 -1
  138. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/staticLayout.js +0 -2
  139. data/frameworks/sproutcore/frameworks/foundation/tests/mixins/string.js +11 -0
  140. data/frameworks/sproutcore/frameworks/foundation/tests/private/tree_item_observer/group_case.js +14 -14
  141. data/frameworks/sproutcore/frameworks/foundation/tests/system/builder.js +2 -2
  142. data/frameworks/sproutcore/frameworks/foundation/tests/system/core_query/jquery_core.js +15 -3
  143. data/frameworks/sproutcore/frameworks/foundation/tests/system/datetime.js +1 -1
  144. data/frameworks/sproutcore/frameworks/foundation/tests/system/locale.js +8 -7
  145. data/frameworks/sproutcore/frameworks/foundation/tests/system/render_context/tag.js +3 -2
  146. data/frameworks/sproutcore/frameworks/foundation/tests/system/request.js +51 -44
  147. data/frameworks/sproutcore/frameworks/foundation/tests/system/root_responder/targetForAction.js +2 -2
  148. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/isPaused.js +4 -4
  149. data/frameworks/sproutcore/frameworks/foundation/tests/system/timer/performAction.js +2 -0
  150. data/frameworks/sproutcore/frameworks/foundation/tests/validators/credit_card.js +9 -9
  151. data/frameworks/sproutcore/frameworks/foundation/tests/validators/number.js +2 -2
  152. data/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +3 -3
  153. data/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +10 -3
  154. data/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +2 -2
  155. data/frameworks/sproutcore/frameworks/foundation/tests/views/pane/append_remove.js +14 -0
  156. data/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +5 -5
  157. data/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +1 -11
  158. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/clippingFrame.js +2 -2
  159. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/destroyLayer.js +2 -4
  160. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/findLayerInParentLayer.js +2 -4
  161. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/insertBefore.js +1 -1
  162. data/frameworks/sproutcore/frameworks/foundation/tests/views/view/layoutStyle.js +0 -2
  163. data/frameworks/sproutcore/frameworks/foundation/validators/password.js +5 -5
  164. data/frameworks/sproutcore/frameworks/foundation/validators/validator.js +4 -2
  165. data/frameworks/sproutcore/frameworks/foundation/views/field.js +5 -8
  166. data/frameworks/sproutcore/frameworks/foundation/views/label.js +21 -5
  167. data/frameworks/sproutcore/frameworks/foundation/views/text_field.js +112 -69
  168. data/frameworks/sproutcore/frameworks/foundation/views/view.js +67 -6
  169. data/frameworks/sproutcore/frameworks/runtime/core.js +51 -2
  170. data/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +4 -1
  171. data/frameworks/sproutcore/frameworks/runtime/system/binding.js +2 -1
  172. data/frameworks/sproutcore/frameworks/runtime/system/enumerator.js +5 -4
  173. data/frameworks/sproutcore/frameworks/runtime/system/index_set.js +6 -1
  174. data/frameworks/sproutcore/frameworks/runtime/system/logger.js +408 -0
  175. data/frameworks/sproutcore/frameworks/runtime/system/object.js +15 -4
  176. data/frameworks/sproutcore/frameworks/runtime/system/selection_set.js +30 -2
  177. data/frameworks/sproutcore/frameworks/runtime/tests/core/IsEqual.js +5 -1
  178. data/frameworks/sproutcore/frameworks/runtime/tests/core/beget.js +1 -1
  179. data/frameworks/sproutcore/frameworks/runtime/tests/core/compare.js +3 -3
  180. data/frameworks/sproutcore/frameworks/runtime/tests/core/guidFor.js +2 -0
  181. data/frameworks/sproutcore/frameworks/runtime/tests/core/isArray.js +1 -1
  182. data/frameworks/sproutcore/frameworks/runtime/tests/core/itemType.js +2 -1
  183. data/frameworks/sproutcore/frameworks/runtime/tests/core/tupleForPropertyPath.js +2 -2
  184. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/propertyChanges.js +1 -1
  185. data/frameworks/sproutcore/frameworks/runtime/tests/mixins/propertyChanges.js +1 -0
  186. data/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +11 -7
  187. data/frameworks/sproutcore/frameworks/runtime/tests/system/error.js +3 -2
  188. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/add.js +18 -1
  189. data/frameworks/sproutcore/frameworks/runtime/tests/system/index_set/remove.js +1 -1
  190. data/frameworks/sproutcore/frameworks/runtime/tests/system/logger.js +165 -0
  191. data/frameworks/sproutcore/frameworks/runtime/tests/system/object/bindings.js +3 -0
  192. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/copy.js +1 -1
  193. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/indexSetForSource.js +13 -0
  194. data/frameworks/sproutcore/frameworks/runtime/tests/system/selection_set/remove.js +24 -0
  195. data/frameworks/sproutcore/frameworks/runtime/tests/system/sparse_array.js +32 -13
  196. data/frameworks/sproutcore/frameworks/testing/english.lproj/runner.css +2 -2
  197. data/frameworks/sproutcore/frameworks/testing/english.lproj/testsuite.css +7 -2
  198. data/frameworks/sproutcore/lib/index.rhtml +6 -20
  199. data/frameworks/sproutcore/themes/standard_theme/Source/sc-theme-repeat-x.psd +0 -0
  200. data/frameworks/sproutcore/themes/standard_theme/english.lproj/button.css +0 -1
  201. data/frameworks/sproutcore/themes/standard_theme/english.lproj/checkbox.css +5 -4
  202. data/frameworks/sproutcore/themes/standard_theme/english.lproj/collection.css +4 -3
  203. data/frameworks/sproutcore/themes/standard_theme/english.lproj/disclosure.css +7 -7
  204. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-repeat-x.png +0 -0
  205. data/frameworks/sproutcore/themes/standard_theme/english.lproj/list_item.css +38 -0
  206. data/frameworks/sproutcore/themes/standard_theme/english.lproj/menu.css +20 -0
  207. data/frameworks/sproutcore/themes/standard_theme/english.lproj/progress.css +1 -0
  208. data/frameworks/sproutcore/themes/standard_theme/english.lproj/radio.css +3 -1
  209. data/frameworks/sproutcore/themes/standard_theme/english.lproj/segmented.css +1 -0
  210. data/frameworks/sproutcore/themes/standard_theme/english.lproj/split_view.css +1 -1
  211. data/frameworks/sproutcore/themes/standard_theme/english.lproj/text_field.css +0 -15
  212. data/gen/data-source/Buildfile +18 -0
  213. data/gen/data-source/README +1 -0
  214. data/gen/data-source/USAGE +15 -0
  215. data/gen/data-source/templates/data_sources/@filename@.js +64 -0
  216. data/lib/sproutcore/builders/combine.rb +23 -0
  217. data/lib/sproutcore/builders/javascript.rb +27 -2
  218. data/lib/sproutcore/buildfile/task.rb +1 -1
  219. data/lib/sproutcore/helpers/entry_sorter.rb +2 -2
  220. data/lib/sproutcore/helpers/static_helper.rb +79 -0
  221. data/lib/sproutcore/models/manifest.rb +2 -2
  222. data/lib/sproutcore/models/target.rb +1 -1
  223. data/lib/sproutcore/tools/build.rb +1 -1
  224. data/lib/sproutcore/tools/docs.rb +3 -3
  225. data/lib/sproutcore/tools/gen.rb +17 -15
  226. data/lib/sproutcore/tools/manifest.rb +9 -9
  227. data/lib/sproutcore/tools/server.rb +3 -3
  228. data/lib/sproutcore/tools.rb +259 -250
  229. data/lib/sproutcore.rb +9 -1
  230. data/spec/buildtasks/manifest/prepare_build_tasks/combine_spec.rb +2 -2
  231. data/spec/fixtures/entry_for_project/frameworks/unrelated/PLACEHOLDER +0 -0
  232. data/spec/fixtures/ordered_entries/apps/no_requires/{lproj → english.lproj}/strings.js +0 -0
  233. data/spec/fixtures/ordered_entries/apps/no_requires/main.js +1 -0
  234. data/spec/fixtures/ordered_entries/apps/no_requires/resources/main_page.js +1 -0
  235. data/spec/fixtures/ordered_entries/apps/no_requires/t.js +1 -0
  236. data/spec/lib/models/manifest/find_entry.rb +12 -0
  237. data/spec/lib/tools/gen_spec.rb +1 -0
  238. data/spec/lib/tools/tools_spec.rb +1 -0
  239. data/sproutcore-abbot.gemspec +36 -44
  240. metadata +43 -44
  241. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/indicator.gif +0 -0
  242. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/sc-theme-sprite.png +0 -0
  243. data/frameworks/sproutcore/frameworks/desktop/english.lproj/images/sticky-note.png +0 -0
  244. data/frameworks/sproutcore/frameworks/desktop/views/form.js +0 -594
  245. data/frameworks/sproutcore/themes/standard_theme/english.lproj/images/sc-theme-sprite.png +0 -0
  246. data/lib/thor/CHANGELOG.rdoc +0 -52
  247. data/lib/thor/LICENSE +0 -20
  248. data/lib/thor/README.markdown +0 -76
  249. data/lib/thor/Rakefile +0 -6
  250. data/lib/thor/Thorfile +0 -45
  251. data/lib/thor/bin/rake2thor +0 -83
  252. data/lib/thor/bin/thor +0 -7
  253. data/lib/thor/lib/thor/error.rb +0 -3
  254. data/lib/thor/lib/thor/options.rb +0 -267
  255. data/lib/thor/lib/thor/ordered_hash.rb +0 -64
  256. data/lib/thor/lib/thor/runner.rb +0 -305
  257. data/lib/thor/lib/thor/task.rb +0 -83
  258. data/lib/thor/lib/thor/task_hash.rb +0 -22
  259. data/lib/thor/lib/thor/tasks/package.rb +0 -18
  260. data/lib/thor/lib/thor/tasks.rb +0 -77
  261. data/lib/thor/lib/thor/util.rb +0 -75
  262. data/lib/thor/lib/thor.rb +0 -170
  263. data/lib/thor/script/destroy +0 -14
  264. data/lib/thor/script/generate +0 -14
  265. data/lib/thor/spec/fixtures/task.thor +0 -10
  266. data/lib/thor/spec/options_spec.rb +0 -271
  267. data/lib/thor/spec/ordered_hash_spec.rb +0 -84
  268. data/lib/thor/spec/spec.opts +0 -1
  269. data/lib/thor/spec/spec_helper.rb +0 -30
  270. data/lib/thor/spec/task_spec.rb +0 -11
  271. data/lib/thor/spec/tasks_spec.rb +0 -28
  272. data/lib/thor/spec/thor_runner_spec.rb +0 -194
  273. data/lib/thor/spec/thor_spec.rb +0 -206
  274. data/lib/thor/spec/util_spec.rb +0 -99
  275. data/lib/thor/task.thor +0 -15
  276. data/lib/thor/thor.gemspec +0 -29
@@ -4,383 +4,540 @@
4
4
  // Portions ©2008-2009 Apple Inc. All rights reserved.
5
5
  // License: Licened under MIT license (see license.js)
6
6
  // ==========================================================================
7
- /*global ActiveXObject */
7
+
8
+ sc_require('system/response');
8
9
 
9
10
  /**
10
- Description to come.
11
+ @class
12
+
13
+ Implements support for Ajax requests using XHR, JSON-P and other prototcols.
14
+
15
+ SC.Request is much like an inverted version of the request/response objects
16
+ you receive when implement HTTP servers.
17
+
18
+ To send a request, you just need to create your request object, configure
19
+ your options, and call send() to initiate the request.
11
20
 
21
+ @extends SC.Object
22
+ @extends SC.Copyable
23
+ @extends SC.Freezable
12
24
  @since SproutCore 1.0
13
25
  */
14
26
 
15
- SC.Request = SC.Object.extend({
27
+ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
28
+ /** @scope SC.Request.prototype */ {
16
29
 
17
- isAsynchronous: true,
18
- rawResponse: null,
19
- error: null,
20
- transportClass: null,
21
- isJSON: false,
30
+ // ..........................................................
31
+ // PROPERTIES
32
+ //
22
33
 
23
34
  /**
24
- Sets up the request object
35
+ Sends the request asynchronously instead of blocking the browser. You
36
+ should almost always make requests asynchronous. You can change this
37
+ options with the async() helper option (or simply set it directly).
38
+
39
+ Defaults to YES.
40
+
41
+ @property {Boolean}
25
42
  */
26
- init: function(){
27
- sc_super() ;
28
- this._headers = {};
29
- },
30
-
43
+ isAsynchronous: YES,
44
+
31
45
  /**
32
- To set headers on the request object
46
+ Processes the request and response as JSON if possible. You can change
47
+ this option with the json() helper method.
48
+
49
+ Defaults to NO
33
50
 
34
- @param {String} key
35
- @param {String} value
36
- @returns {SC.Request} receiver
51
+ @property {Boolean}
37
52
  */
38
- header: function(key, value) {
39
- if (typeof key == 'object' && !value) {
40
- for (var headerKey in key) {
41
- this.header(headerKey,key[headerKey]) ;
42
- }
43
- return this;
44
- }
45
-
46
- if (typeof key == 'string' && !value) {
47
- return this._headers[key] ;
48
- }
49
-
50
- this.propertyWillChange('headers') ;
51
-
52
- //set value for key
53
- this._headers[key] = value ;
53
+ isJSON: NO,
54
+
55
+ /**
56
+ Process the request and response as XML if possible. You can change this
57
+ option with the xml() helper method.
54
58
 
55
- this.propertyDidChange('headers') ;
56
- return this ;
57
- },
59
+ Defaults to NO
60
+
61
+ @property {Boolean}
62
+ */
63
+ isXML: NO,
58
64
 
59
65
  /**
60
- Will fire the actual request.
61
-
62
- @param {String} body (optional)
63
- @returns {SC.Request} receiver
64
- */
65
- send: function(body) {
66
- var request = this ;
67
-
68
- var isJSON = request.get('isJSON');
69
-
70
- // Set the content-type to JSON (many browsers will otherwise default it
71
- // to XML).
72
- if (isJSON) request.header('Content-Type', 'application/json');
66
+ Current set of headers for the request
67
+ */
68
+ headers: function() {
69
+ var ret = this._headers ;
70
+ if (!ret) ret = this._headers = {} ;
71
+ return ret ;
72
+ }.property().cacheable(),
73
+
74
+ /**
75
+ Underlying response class to actually handle this request. Currently the
76
+ only supported option is SC.XHRResponse which uses a traditional
77
+ XHR transport.
73
78
 
74
- if (body) {
75
- if (isJSON) {
76
- body=SC.json.encode(body);
77
- if(body===undefined) console.error('There was an error encoding to JSON');
78
- }
79
- request.set('body', body) ;
80
- }
81
- SC.Request.manager.sendRequest(request) ;
82
- return request ;
83
- },
79
+ @property {SC.Response}
80
+ */
81
+ responseClass: SC.XHRResponse,
84
82
 
85
83
  /**
86
- Set up notifications.
84
+ The original request for copied requests.
87
85
 
88
- @param {Object} target
89
- @param {String|function} action
90
- @param {Hash} params
91
- @returns {SC.Request} receiver
86
+ @property {SC.Request}
92
87
  */
93
- notify: function(target, action, params) {
94
- if (SC.typeOf(action) === SC.T_STRING) action = target[action];
95
- this.set('notifyTarget', target)
96
- .set('notifyAction', action)
97
- .set('notifyParams', params);
98
- return this;
99
- },
88
+ source: null,
100
89
 
101
90
  /**
102
- Response method
91
+ The URL this request to go to.
103
92
 
104
- @returns {Object} response
93
+ @param {String}
105
94
  */
106
- response: function() {
107
- var response = this.get("rawResponse") ;
108
- if (!response || !SC.$ok(response) || response.responseText.trim()==='') {
109
- return response ;
110
- }
111
-
112
- if (this.get("isJSON")) {
113
- var source = response.responseText ;
114
- try{
115
- var json = SC.json.decode(source) ;
116
- }catch(e){
117
- json = response.responseText ;
118
- }
119
- //TODO cache this value?
120
- return json ;
121
- }
122
-
123
- if(response.responseXML) return response.responseXML ;
124
- return response.responseText ;
125
- }.property('rawResponse').cacheable()
95
+ address: null,
126
96
 
127
- });
128
-
129
- /**
130
- Helper method for quickly setting up a GET request.
97
+ /**
98
+ The HTTP method to use.
99
+
100
+ @param {String}
101
+ */
102
+ type: 'GET',
131
103
 
132
- @param {String} address url of request
133
- @returns {SC.Request} receiver
134
- */
135
- SC.Request.getUrl = function(address) {
136
- var req = SC.Request.create() ;
137
- req.set('address', address) ;
138
- req.set('type', 'GET') ;
104
+ /**
105
+ The body of the request. May be an object is isJSON or isXML is set,
106
+ otherwise should be a string.
107
+ */
108
+ body: null,
139
109
 
140
- return req ;
141
- };
110
+ /**
111
+ The body, encoded as JSON or XML if needed.
112
+ */
113
+ encodedBody: function() {
114
+ // TODO: support XML
115
+ var ret = this.get('body');
116
+ if (ret && this.get('isJSON')) ret = SC.json.encode(ret);
117
+ return ret ;
118
+ }.property('isJSON', 'isXML', 'body').cacheable(),
142
119
 
143
- /**
144
- Helper method for quickly setting up a POST request.
145
-
146
- @param {String} address url of request
147
- @param {String} body
148
- @returns {SC.Request} receiver
149
- */
150
- SC.Request.postUrl = function(address, body) {
151
- var req = SC.Request.create() ;
152
- req.set('address',address) ;
153
- if(body) req.set('body', body) ;
154
- req.set('type', 'POST') ;
120
+ // ..........................................................
121
+ // CALLBACKS
122
+ //
155
123
 
156
- return req ;
157
- };
158
-
159
- /**
160
- Helper method for quickly setting up a DELETE request.
124
+ /**
125
+ Invoked on the original request object just before a copied request is
126
+ frozen and then sent to the server. This gives you one last change to
127
+ fixup the request; possibly adding headers and other options.
128
+
129
+ If you do not want the request to actually send, call cancel().
130
+
131
+ @param {SC.Request} request a copy of the request, not frozen
132
+ @returns {void}
133
+ */
134
+ willSend: function(request, response) {},
161
135
 
162
- @param {String} address url of request
163
- @returns {SC.Request} receiver
164
- */
165
- SC.Request.deleteUrl = function(address) {
166
- var req = SC.Request.create() ;
167
- req.set('address',address) ;
168
- req.set('type', 'DELETE') ;
136
+ /**
137
+ Invoked on the original request object just after the request is sent to
138
+ the server. You might use this callback to update some state in your
139
+ application.
140
+
141
+ The passed request is a frozen copy of the request, indicating the
142
+ options set at the time of the request.
143
+
144
+ @param {SC.Request} request a copy of the request, frozen
145
+ @param {SC.Response} response the object that will carry the response
146
+ @returns {void}
147
+ */
148
+ didSend: function(request, response) {},
169
149
 
170
- return req ;
171
- };
172
-
173
- /**
174
- Helper method for quickly setting up a PUT request.
150
+ /**
151
+ Invoked when a response has been received but not yet processed. This is
152
+ your chance to fixup the response based on the results. If you don't want
153
+ to continue processing the response call response.cancel().
154
+
155
+ @param {SC.Response} response the response
156
+ @returns {void}
157
+ */
158
+ willReceive: function(request, response) {},
175
159
 
176
- @param {String} address url of request
177
- @param {String} body
178
- @returns {SC.Request} receiver
179
- */
180
- SC.Request.putUrl = function(address, body) {
181
- var req = SC.Request.create() ;
182
- req.set('address',address) ;
183
- if(body) req.set('body', body) ;
184
- req.set('type', 'PUT') ;
160
+ /**
161
+ Invoked after a response has been processed but before any listeners are
162
+ notified. You can do any standard processing on the request at this
163
+ point. If you don't want to allow notifications to continue, call
164
+ response.cancel()
165
+
166
+ @param {SC.Response} response reponse
167
+ @returns {void}
168
+ */
169
+ didReceive: function(request, response) {},
185
170
 
186
- return req ;
187
- };
171
+ // ..........................................................
172
+ // HELPER METHODS
173
+ //
188
174
 
189
- /**
190
- The request manager.
191
- More description to come.
192
- */
193
- SC.Request.manager = SC.Object.create( SC.DelegateSupport, {
194
- maxRequests: 2,
195
-
196
- currentRequests: [],
197
- queue: [],
198
-
199
- canLoadAnotherRequest: function() {
200
- return (this.get('numberOfCurrentRequests') < this.get('maxRequests')) ;
201
- }.property('numberOfCurrentRequests', 'maxRequests'),
175
+ COPY_KEYS: 'isAsynchronous isJSON isXML address type body responseClass willSend didSend willReceive didReceive'.w(),
202
176
 
203
- numberOfCurrentRequests: function() {
204
- return this.get('currentRequests').length ;
205
- }.property('currentRequests'),
206
-
207
- numberOfRequests: function() {
208
- return this.get('queue').length ;
209
- }.property('queue'),
210
-
211
- sendRequest: function(request) {
212
- if(!request) return;
177
+ /**
178
+ Returns a copy of the current request. This will only copy certain
179
+ properties so if you want to add additional properties to the copy you
180
+ will need to override copy() in a subclass.
213
181
 
214
- request = {
215
- request: request,
216
- action: request.get('notifyAction'),
217
- target: request.get('notifyTarget'),
218
- params: request.get('notifyParams') };
182
+ @returns {SC.Request} new request
183
+ */
184
+ copy: function() {
185
+ var ret = {},
186
+ keys = this.COPY_KEYS,
187
+ loc = keys.length,
188
+ key, listeners, headers;
189
+
190
+ while(--loc>=0) {
191
+ key = keys[loc];
192
+ if (this.hasOwnProperty(key)) ret[key] = this.get(key);
193
+ }
219
194
 
220
- this.propertyWillChange("queue");
221
- this.get('queue').pushObject(request);
222
- this.propertyDidChange("queue");
195
+ if (this.hasOwnProperty('listeners')) {
196
+ ret.listeners = SC.copy(this.get('listeners'));
197
+ }
223
198
 
224
- this.fireRequestIfNeeded();
225
- },
226
-
227
- removeRequest: function(request) {
228
- this.get('queue').removeObject(request);
229
- return YES;
230
- },
231
-
232
- cancelAllRequests: function() {
233
- var r, xhrRequest;
234
- this.set('queue', []);
235
- var activeRequests=this.get('currentRequests');
236
- while(r=activeRequests.shiftObject()){
237
- xhrRequest = r.get('request');
238
- xhrRequest.abort();
199
+ if (this.hasOwnProperty('_headers')) {
200
+ ret._headers = SC.copy(this._headers);
239
201
  }
240
- return YES;
202
+
203
+ ret.source = this.get('source') || this ;
204
+
205
+ return this.constructor.create(ret);
241
206
  },
242
207
 
243
- fireRequestIfNeeded: function() {
244
- if (this.canLoadAnotherRequest()) {
245
- this.propertyWillChange('queue') ;
246
- var item = this.get('queue').shiftObject() ;
247
- this.propertyDidChange('queue') ;
248
-
249
- if (item) {
250
- var transportClass = item.request.get('transportClass') ;
251
- if (!transportClass) transportClass = this.get('transportClass') ;
252
-
253
- if (transportClass) {
254
- var transport = this.transportClass.create(item) ;
255
- if (transport) {
256
- item.request.set('transport', transport) ;
257
- this._transportDidOpen(transport) ;
258
- }
259
- }
208
+ /**
209
+ To set headers on the request object. Pass either a single key/value
210
+ pair or a hash of key/value pairs. If you pass only a header name, this
211
+ will return the current value of the header.
212
+
213
+ @param {String|Hash} key
214
+ @param {String} value
215
+ @returns {SC.Request|Object} receiver
216
+ */
217
+ header: function(key, value) {
218
+ var headers;
219
+
220
+ if (SC.typeOf(key) === SC.T_STRING) {
221
+ headers = this._headers ;
222
+ if (arguments.length===1) {
223
+ return headers ? headers[key] : null;
224
+ } else {
225
+ this.propertyWillChange('headers');
226
+ if (!headers) headers = this._headers = {};
227
+ headers[key] = value;
228
+ this.propertyDidChange('headers');
229
+ return this;
260
230
  }
231
+
232
+ // handle parsing hash of parameters
233
+ } else if (value === undefined) {
234
+ headers = key;
235
+ this.beginPropertyChanges();
236
+ for(key in headers) {
237
+ if (!headers.hasOwnProperty(key)) continue ;
238
+ this.header(key, headers[key]);
239
+ }
240
+ this.endPropertyChanges();
241
+ return this;
261
242
  }
262
- }.observes('currentRequests'),
263
-
264
- _transportDidOpen: function(transport) {
265
- this.propertyWillChange('currentRequests') ;
266
- this.get('currentRequests').pushObject(transport) ;
267
- this.propertyDidChange('currentRequests') ;
268
- transport.fire() ;
243
+
244
+ return this ;
269
245
  },
270
246
 
271
- transportDidClose: function(request) {
272
- this.propertyWillChange('currentRequests') ;
273
- this.get('currentRequests').removeObject(request) ;
274
- this.propertyDidChange('currentRequests') ;
275
- }
247
+ /**
248
+ Converts the current request to use JSON.
249
+
250
+ @property {Boolean} flag YES to make JSON, NO or undefined
251
+ @returns {SC.Request} receiver
252
+ */
253
+ json: function(flag) {
254
+ if (flag === undefined) flag = YES;
255
+ if (flag) this.set('isXML', NO);
256
+ return this.set('isJSON', flag);
257
+ },
276
258
 
277
- });
278
-
279
- // abstract superclass, creates no-op objects
280
- SC.RequestTransport = SC.Object.extend({
259
+ /**
260
+ Converts the current request to use XML.
261
+
262
+ @property {Boolean} flag YES to make XML, NO or undefined
263
+ @returns {SC.Request} recevier
264
+ */
265
+ xml: function(flag) {
266
+ if (flag === undefined) flag = YES ;
267
+ if (flag) this.set('isJSON', NO);
268
+ return this.set('isXML', flag);
269
+ },
281
270
 
282
- fire: function() {
283
- SC.Request.manager.transportDidClose(this) ;
284
- }
271
+ /**
272
+ Called just before a request is enqueued. This will encode the body
273
+ into JSON if it is not already encoded.
274
+ */
275
+ _prep: function() {
276
+ var hasContentType = !!this.header('Content-Type');
277
+ if (this.get('isJSON') && !hasContentType) {
278
+ this.header('Content-Type', 'application/json');
279
+ } else if (this.get('isXML') && !hasContentType) {
280
+ this.header('Content-Type', 'text/xml');
281
+ }
282
+ return this ;
283
+ },
285
284
 
286
- });
285
+ /**
286
+ Will fire the actual request. If you have set the request to use JSON
287
+ mode then you can pass any object that can be converted to JSON as the
288
+ body. Otherwise you should pass a string body.
289
+
290
+ @param {String|Object} body (optional)
291
+ @returns {SC.Response} new response object
292
+ */
293
+ send: function(body) {
294
+ if (body) this.set('body', body);
295
+ return SC.Request.manager.sendRequest(this.copy()._prep());
296
+ },
287
297
 
288
- SC.XHRRequestTransport = SC.RequestTransport.extend({
298
+ /**
299
+ Resends the current request. This is more efficient than calling send()
300
+ for requests that have already been used in a send. Otherwise acts just
301
+ like send(). Does not take a body argument.
302
+
303
+ @returns {SC.Response} new response object
304
+ */
305
+ resend: function() {
306
+ var req = this.get('source') ? this : this.copy()._prep();
307
+ return SC.Request.manager.sendRequest(req);
308
+ },
289
309
 
290
- fire: function() {
291
-
292
- var tryThese = function() {
293
- for (var i=0; i < arguments.length; i++) {
294
- try {
295
- var item = arguments[i]() ;
296
- return item ;
297
- } catch (e) {}
298
- }
299
- return NO;
300
- };
310
+ /**
311
+ Configures a callback to execute when a request completes. You must pass
312
+ at least a target and action/method to this and optionally a status code.
313
+ You may also pass additional parameters which will be passed along to your
314
+ callback.
301
315
 
302
- var rawRequest = tryThese(
303
- function() { return new XMLHttpRequest(); },
304
- function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
305
- function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
306
- );
316
+ h2. Scoping With Status Codes
307
317
 
308
- var request = this.get('request') ;
318
+ If you pass a status code as the first option to this method, then your
319
+ notification callback will only be called if the response status matches
320
+ the code. For example, if you pass 201 (or SC.Request.CREATED) then
321
+ your method will only be called if the response status from the server
322
+ is 201.
309
323
 
310
- rawRequest.source = request;
324
+ You can also pass "generic" status codes such as 200, 300, or 400, which
325
+ will be invoked anytime the status code is the range if a more specific
326
+ notifier was not registered first and returned YES.
311
327
 
328
+ Finally, passing a status code of 0 or no status at all will cause your
329
+ method to be executed no matter what the resulting status is unless a
330
+ more specific notifier was registered and returned YES.
312
331
 
313
- //Part of the fix for IE
314
- var transport=this;
315
- var handleReadyStateChange = function() {
316
- return transport.finishRequest(rawRequest) ;
317
- };
318
- //End of the fix for IE
332
+ h2. Callback Format
319
333
 
320
- var async = (request.get('isAsynchronous') ? YES : NO) ;
321
- if (async) {
322
- if (!SC.browser.msie) {
323
- SC.Event.add(rawRequest, 'readystatechange', this, handleReadyStateChange, rawRequest) ;
324
- } else rawRequest.onreadystatechange = handleReadyStateChange;
325
- }
334
+ Your notification callback should expect to receive the Response object
335
+ as the first parameter plus any additional parameters that you pass.
326
336
 
337
+ @param {Object} target
338
+ @param {String|function} action
339
+ @param {Hash} params
340
+ @returns {SC.Request} receiver
341
+ */
342
+ notify: function(status, target, action) {
343
+
344
+ // normalize status
345
+ var hasStatus = YES, params ;
346
+ if (SC.typeOf(status) !== SC.T_NUMBER) {
347
+ params = SC.A(arguments).slice(2);
348
+ action = target;
349
+ target = status;
350
+ status = 0 ;
351
+ hasStatus = NO ;
352
+ } else params = SC.A(arguments).slice(3);
353
+
354
+ var listeners = this.get('listeners');
355
+ if (!listeners) this.set('listeners', listeners = {});
356
+ listeners[status] = { target: target, action: action, params: params };
357
+
358
+ return this;
359
+ }
327
360
 
361
+ });
362
+
363
+ SC.Request.mixin(/** @scope SC.Request */ {
364
+
365
+ /**
366
+ Helper method for quickly setting up a GET request.
367
+
368
+ @param {String} address url of request
369
+ @returns {SC.Request} receiver
370
+ */
371
+ getUrl: function(address) {
372
+ return SC.Request.create().set('address', address).set('type', 'GET');
373
+ },
374
+
375
+ /**
376
+ Helper method for quickly setting up a POST request.
377
+
378
+ @param {String} address url of request
379
+ @param {String} body
380
+ @returns {SC.Request} receiver
381
+ */
382
+ postUrl: function(address, body) {
383
+ var req = SC.Request.create().set('address', address).set('type', 'POST');
384
+ if(body) req.set('body', body) ;
385
+ return req ;
386
+ },
387
+
388
+ /**
389
+ Helper method for quickly setting up a DELETE request.
390
+
391
+ @param {String} address url of request
392
+ @returns {SC.Request} receiver
393
+ */
394
+ deleteUrl: function(address) {
395
+ return SC.Request.create().set('address', address).set('type', 'DELETE');
396
+ },
397
+
398
+ /**
399
+ Helper method for quickly setting up a PUT request.
400
+
401
+ @param {String} address url of request
402
+ @param {String} body
403
+ @returns {SC.Request} receiver
404
+ */
405
+ putUrl: function(address, body) {
406
+ var req = SC.Request.create().set('address', address).set('type', 'PUT');
407
+ if(body) req.set('body', body) ;
408
+ return req ;
409
+ }
410
+
411
+ });
412
+
413
+
414
+
415
+ /**
416
+ The request manager coordinates all of the active XHR requests. It will
417
+ only allow a certain number of requests to be active at a time; queuing
418
+ any others. This allows you more precise control over which requests load
419
+ in which order.
420
+ */
421
+ SC.Request.manager = SC.Object.create( SC.DelegateSupport, {
422
+
423
+ /**
424
+ Maximum number of concurrent requests allowed. 6 for all browsers.
328
425
 
329
- rawRequest.open( request.get('type'), request.get('address'), async ) ;
426
+ @property {Number}
427
+ */
428
+ maxRequests: 6,
429
+
430
+ /**
431
+ Current requests that are inflight.
330
432
 
331
- // headers need to be set *After* the open call.
332
- var headers = request._headers ;
333
- for (var headerKey in headers) {
334
- rawRequest.setRequestHeader(headerKey, headers[headerKey]) ;
335
- }
433
+ @property {Array}
434
+ */
435
+ inflight: [],
436
+
437
+ /**
438
+ Requests that are pending and have not been started yet.
439
+
440
+ @property {Array}
441
+ */
442
+ pending: [],
443
+
444
+ // ..........................................................
445
+ // METHODS
446
+ //
447
+
448
+ /**
449
+ Invoked by the send() method on a request. This will create a new low-
450
+ level transport object and queue it if needed.
336
451
 
337
- rawRequest.send(request.get('body')) ;
452
+ @param {SC.Request} request the request to send
453
+ @returns {SC.Object} response object
454
+ */
455
+ sendRequest: function(request) {
456
+ if (!request) return null ;
338
457
 
339
- if (!async) this.finishRequest(rawRequest) ;
458
+ // create low-level transport. copy all critical data for request over
459
+ // so that if the request has been reconfigured the transport will still
460
+ // work.
461
+ var response = request.get('responseClass').create({ request: request });
462
+
463
+ // add to pending queue
464
+ this.get('pending').pushObject(response);
465
+ this.fireRequestIfNeeded();
340
466
 
341
- return rawRequest ;
467
+ return response ;
342
468
  },
343
-
344
- didSucceed: function(request) {
345
- var status = null ;
346
- try {
347
- status = request.status || 0;
348
- } catch (e) {}
349
- return !status || (status >= 200 && status < 300) ;
350
- },
351
-
352
- finishRequest: function(request) {
353
-
354
- var readyState = request.readyState ;
355
- var didSucceed = !request ? NO : this.didSucceed(request) ;
469
+
470
+ /**
471
+ Cancels a specific request. If the request is pending it will simply
472
+ be removed. Otherwise it will actually be cancelled.
356
473
 
357
- if (readyState == 4) {
358
- request._complete = YES ;
474
+ @param {Object} response a response object
475
+ @returns {Boolean} YES if cancelled
476
+ */
477
+ cancel: function(response) {
478
+
479
+ var pending = this.get('pending'),
480
+ inflight = this.get('inflight'),
481
+ idx ;
482
+
483
+ if (pending.indexOf(response) >= 0) {
484
+ this.propertyWillChange('pending');
485
+ pending.removeObject(response);
486
+ this.propertyDidChange('pending');
487
+ return YES;
359
488
 
360
- if (didSucceed) {
361
- var response = request ;
362
- request.source.set('rawResponse', response) ;
363
- } else {
364
- var error = SC.$error("HTTP Request failed", "Fail", -1) ;
365
- error.set("request",request) ;
366
- request.source.set('rawResponse', error) ;
367
- }
368
- if (this.target && this.action) {
369
- SC.RunLoop.begin();
370
- this.action.call(this.target, request.source, this.params);
371
- SC.RunLoop.end();
372
- }
489
+ } else if (inflight.indexOf(response) >= 0) {
373
490
 
374
- SC.Request.manager.transportDidClose(this) ;
375
- }
376
-
377
- if (readyState == 4) {
378
- // avoid memory leak in MSIE: clean up
379
- request.onreadystatechange = function() {} ;
380
- }
381
- }
491
+ response.cancel();
492
+
493
+ inflight.removeObject(response);
494
+ this.fireRequestIfNeeded();
495
+ return YES;
496
+
497
+ } else return NO ;
498
+ },
499
+
500
+ /**
501
+ Cancels all inflight and pending requests.
502
+
503
+ @returns {Boolean} YES if any items were cancelled.
504
+ */
505
+ cancelAll: function() {
506
+ if (this.get('pending').length || this.get('inflight').length) {
507
+ this.set('pending', []);
508
+ this.get('inflight').forEach(function(r) { r.cancel(); });
509
+ this.set('inflight', []);
510
+ return YES;
511
+
512
+ } else return NO ;
513
+ },
514
+
515
+ /**
516
+ Checks the inflight queue. If there is an open slot, this will move a
517
+ request from pending to inflight.
518
+
519
+ @returns {Object} receiver
520
+ */
521
+ fireRequestIfNeeded: function() {
522
+ var pending = this.get('pending'),
523
+ inflight = this.get('inflight'),
524
+ max = this.get('maxRequests'),
525
+ next ;
526
+
527
+ if ((pending.length>0) && (inflight.length<max)) {
528
+ next = pending.shiftObject();
529
+ inflight.pushObject(next);
530
+ next.fire();
531
+ }
532
+ },
382
533
 
534
+ /**
535
+ Called by a response/transport object when finishes running. Removes
536
+ the transport from the queue and kicks off the next one.
537
+ */
538
+ transportDidClose: function(response) {
539
+ this.get('inflight').removeObject(response);
540
+ this.fireRequestIfNeeded();
541
+ }
383
542
 
384
543
  });
385
-
386
- SC.Request.manager.set('transportClass', SC.XHRRequestTransport) ;