sproutcore 0.9.1 → 0.9.2

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 (208) hide show
  1. data/History.txt +233 -0
  2. data/Manifest.txt +67 -34
  3. data/bin/sc-build +12 -1
  4. data/bin/sc-gen +1 -1
  5. data/bin/sproutcore +14 -0
  6. data/clients/sc_docs/controllers/docs.js +38 -8
  7. data/clients/sc_docs/english.lproj/body.css +80 -127
  8. data/clients/sc_docs/english.lproj/body.rhtml +43 -23
  9. data/clients/sc_docs/english.lproj/no_docs.rhtml +2 -1
  10. data/clients/sc_docs/english.lproj/tabs.rhtml +16 -0
  11. data/clients/sc_docs/main.js +14 -9
  12. data/clients/sc_docs/models/doc.js +1 -1
  13. data/clients/sc_docs/tests/controllers/docs.rhtml +1 -2
  14. data/clients/sc_docs/tests/models/doc.rhtml +1 -2
  15. data/clients/sc_docs/tests/views/doc_frame.rhtml +1 -2
  16. data/clients/sc_docs/tests/views/doc_label_view.rhtml +1 -2
  17. data/clients/sc_docs/views/doc_frame.js +1 -1
  18. data/clients/sc_test_runner/controllers/runner.js +31 -8
  19. data/clients/sc_test_runner/english.lproj/body.css +62 -122
  20. data/clients/sc_test_runner/english.lproj/body.rhtml +62 -26
  21. data/clients/sc_test_runner/main.js +1 -6
  22. data/clients/sc_test_runner/models/test.js +14 -1
  23. data/clients/sc_test_runner/views/runner_frame.js +4 -2
  24. data/clients/view_builder/builders/builder.js +339 -0
  25. data/clients/view_builder/builders/button.js +81 -0
  26. data/clients/view_builder/controllers/document.js +21 -0
  27. data/clients/view_builder/core.js +19 -0
  28. data/clients/view_builder/english.lproj/body.css +77 -0
  29. data/clients/view_builder/english.lproj/body.rhtml +41 -0
  30. data/clients/{sc_docs → view_builder}/english.lproj/controls.css +0 -0
  31. data/clients/view_builder/english.lproj/strings.js +14 -0
  32. data/clients/view_builder/main.js +38 -0
  33. data/clients/view_builder/tests/controllers/document.rhtml +20 -0
  34. data/clients/view_builder/tests/views/builder.rhtml +20 -0
  35. data/clients/view_builder/views/builder.js +23 -0
  36. data/frameworks/prototype/prototype.js +1 -1
  37. data/frameworks/sproutcore/Core.js +32 -7
  38. data/frameworks/sproutcore/README +1 -1
  39. data/frameworks/sproutcore/animation/animation.js +411 -0
  40. data/frameworks/sproutcore/controllers/array.js +17 -9
  41. data/frameworks/sproutcore/controllers/collection.js +9 -110
  42. data/frameworks/sproutcore/controllers/controller.js +1 -1
  43. data/frameworks/sproutcore/controllers/object.js +2 -1
  44. data/frameworks/sproutcore/drag/drag.js +267 -56
  45. data/frameworks/sproutcore/drag/drag_data_source.js +24 -16
  46. data/frameworks/sproutcore/drag/drag_source.js +53 -42
  47. data/frameworks/sproutcore/drag/drop_target.js +2 -2
  48. data/frameworks/sproutcore/english.lproj/buttons.css +337 -236
  49. data/frameworks/sproutcore/english.lproj/core.css +115 -0
  50. data/frameworks/sproutcore/english.lproj/icons.css +227 -0
  51. data/{clients/sc_docs → frameworks/sproutcore}/english.lproj/images/indicator.gif +0 -0
  52. data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
  53. data/frameworks/sproutcore/english.lproj/images/sc-theme-ysprite.png +0 -0
  54. data/frameworks/sproutcore/english.lproj/images/shared-icons.png +0 -0
  55. data/frameworks/sproutcore/english.lproj/menu.css +1 -1
  56. data/frameworks/sproutcore/english.lproj/strings.js +1 -1
  57. data/frameworks/sproutcore/english.lproj/theme.css +405 -31
  58. data/frameworks/sproutcore/foundation/application.js +15 -11
  59. data/frameworks/sproutcore/foundation/benchmark.js +1 -1
  60. data/frameworks/sproutcore/foundation/binding.js +2 -2
  61. data/frameworks/sproutcore/foundation/date.js +1 -1
  62. data/frameworks/sproutcore/foundation/error.js +1 -1
  63. data/frameworks/sproutcore/foundation/input_manager.js +32 -21
  64. data/frameworks/sproutcore/foundation/mock.js +1 -1
  65. data/frameworks/sproutcore/foundation/node_descriptor.js +9 -6
  66. data/frameworks/sproutcore/foundation/object.js +249 -177
  67. data/frameworks/sproutcore/foundation/page.js +5 -2
  68. data/frameworks/sproutcore/foundation/path_module.js +11 -10
  69. data/frameworks/sproutcore/foundation/responder.js +5 -2
  70. data/frameworks/sproutcore/foundation/routes.js +17 -13
  71. data/frameworks/sproutcore/foundation/run_loop.js +249 -11
  72. data/frameworks/sproutcore/foundation/server.js +1 -1
  73. data/frameworks/sproutcore/foundation/set.js +3 -3
  74. data/frameworks/sproutcore/foundation/string.js +5 -3
  75. data/frameworks/sproutcore/foundation/timer.js +371 -0
  76. data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
  77. data/frameworks/sproutcore/foundation/unittest.js +3 -3
  78. data/frameworks/sproutcore/foundation/utils.js +161 -2
  79. data/frameworks/sproutcore/globals/panels.js +1 -1
  80. data/frameworks/sproutcore/globals/popups.js +4 -3
  81. data/frameworks/sproutcore/globals/window.js +44 -4
  82. data/frameworks/sproutcore/lib/button_views.rb +328 -0
  83. data/frameworks/sproutcore/lib/collection_view.rb +80 -0
  84. data/frameworks/sproutcore/lib/core_views.rb +281 -0
  85. data/frameworks/sproutcore/lib/form_views.rb +253 -0
  86. data/frameworks/sproutcore/lib/index.rhtml +2 -0
  87. data/frameworks/sproutcore/lib/menu_views.rb +88 -0
  88. data/frameworks/sproutcore/{foundation → mixins}/array.js +60 -29
  89. data/frameworks/sproutcore/mixins/control.js +265 -0
  90. data/frameworks/sproutcore/mixins/delegate_support.js +66 -0
  91. data/frameworks/sproutcore/{foundation → mixins}/observable.js +176 -6
  92. data/frameworks/sproutcore/mixins/scrollable.js +245 -0
  93. data/frameworks/sproutcore/mixins/selection_support.js +148 -0
  94. data/frameworks/sproutcore/mixins/validatable.js +152 -0
  95. data/frameworks/sproutcore/models/collection.js +5 -5
  96. data/frameworks/sproutcore/models/record.js +1 -1
  97. data/frameworks/sproutcore/models/store.js +1 -1
  98. data/frameworks/sproutcore/panes/dialog.js +1 -1
  99. data/frameworks/sproutcore/panes/manager.js +1 -1
  100. data/frameworks/sproutcore/panes/menu.js +1 -1
  101. data/frameworks/sproutcore/panes/overlay.js +2 -2
  102. data/frameworks/sproutcore/panes/panel.js +1 -1
  103. data/frameworks/sproutcore/panes/picker.js +1 -1
  104. data/frameworks/sproutcore/tests/controllers/array.rhtml +44 -4
  105. data/frameworks/sproutcore/tests/foundation/timer/invalidate.rhtml +33 -0
  106. data/frameworks/sproutcore/tests/foundation/timer/invokeLater.rhtml +145 -0
  107. data/frameworks/sproutcore/tests/foundation/timer/isPaused.rhtml +70 -0
  108. data/frameworks/sproutcore/tests/foundation/timer/schedule.rhtml +145 -0
  109. data/frameworks/sproutcore/tests/views/{scroll.rhtml → checkbox.rhtml} +3 -3
  110. data/frameworks/sproutcore/tests/views/{collection.rhtml → collection/base.rhtml} +33 -32
  111. data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +260 -0
  112. data/frameworks/sproutcore/tests/views/image_cell.rhtml +19 -0
  113. data/frameworks/sproutcore/tests/views/label_item.rhtml +2 -4
  114. data/frameworks/sproutcore/tests/views/list.rhtml +2 -3
  115. data/frameworks/sproutcore/tests/views/list_item.rhtml +20 -0
  116. data/frameworks/sproutcore/tests/views/slider.rhtml +20 -0
  117. data/frameworks/sproutcore/tests/views/text_cell.rhtml +19 -0
  118. data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +395 -0
  119. data/frameworks/sproutcore/tests/views/view/frame.rhtml +353 -0
  120. data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +347 -0
  121. data/frameworks/sproutcore/tests/views/view/isVisibleInWindow.rhtml +148 -0
  122. data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +468 -0
  123. data/frameworks/sproutcore/validators/credit_card.js +33 -13
  124. data/frameworks/sproutcore/validators/date.js +26 -6
  125. data/frameworks/sproutcore/validators/email.js +21 -3
  126. data/frameworks/sproutcore/validators/not_empty.js +11 -1
  127. data/frameworks/sproutcore/validators/number.js +18 -4
  128. data/frameworks/sproutcore/validators/password.js +12 -1
  129. data/frameworks/sproutcore/validators/validator.js +204 -194
  130. data/frameworks/sproutcore/views/{button.js → button/button.js} +96 -94
  131. data/frameworks/sproutcore/views/button/checkbox.js +29 -0
  132. data/frameworks/sproutcore/views/button/disclosure.js +42 -0
  133. data/frameworks/sproutcore/views/button/radio.js +29 -0
  134. data/frameworks/sproutcore/views/{collection.js → collection/collection.js} +1373 -1024
  135. data/frameworks/sproutcore/views/collection/grid.js +124 -46
  136. data/frameworks/sproutcore/views/collection/image_cell.js +17 -46
  137. data/frameworks/sproutcore/views/collection/list.js +45 -35
  138. data/frameworks/sproutcore/views/collection/source_list.js +386 -0
  139. data/frameworks/sproutcore/views/collection/table.js +118 -0
  140. data/frameworks/sproutcore/views/container.js +7 -2
  141. data/frameworks/sproutcore/views/error_explanation.js +23 -10
  142. data/frameworks/sproutcore/views/{checkbox_field.js → field/checkbox_field.js} +16 -6
  143. data/frameworks/sproutcore/views/field/field.js +219 -0
  144. data/frameworks/sproutcore/views/{radio_field.js → field/radio_field.js} +27 -12
  145. data/frameworks/sproutcore/views/{select_field.js → field/select_field.js} +116 -90
  146. data/frameworks/sproutcore/views/{text_field.js → field/text_field.js} +57 -8
  147. data/frameworks/sproutcore/views/{textarea_field.js → field/textarea_field.js} +13 -3
  148. data/frameworks/sproutcore/views/filter_button.js +2 -2
  149. data/frameworks/sproutcore/views/form.js +3 -3
  150. data/frameworks/sproutcore/views/image.js +128 -21
  151. data/frameworks/sproutcore/views/inline_text_editor.js +1 -1
  152. data/frameworks/sproutcore/views/label.js +149 -92
  153. data/frameworks/sproutcore/views/list_item.js +225 -0
  154. data/frameworks/sproutcore/views/menu_item.js +10 -4
  155. data/frameworks/sproutcore/views/pagination.js +11 -4
  156. data/frameworks/sproutcore/views/popup_button.js +25 -21
  157. data/frameworks/sproutcore/views/popup_menu.js +10 -4
  158. data/frameworks/sproutcore/views/progress.js +29 -16
  159. data/frameworks/sproutcore/views/radio_group.js +1 -1
  160. data/frameworks/sproutcore/views/scroll.js +60 -20
  161. data/frameworks/sproutcore/views/segmented.js +1 -1
  162. data/frameworks/sproutcore/views/slider.js +132 -0
  163. data/frameworks/sproutcore/views/source_list_group.js +130 -0
  164. data/frameworks/sproutcore/views/spinner.js +1 -1
  165. data/frameworks/sproutcore/views/split.js +292 -0
  166. data/frameworks/sproutcore/views/split_divider.js +109 -0
  167. data/frameworks/sproutcore/views/tab.js +1 -1
  168. data/frameworks/sproutcore/views/toolbar.js +1 -1
  169. data/frameworks/sproutcore/views/view.js +1272 -591
  170. data/generators/client/templates/english.lproj/body.css +1 -1
  171. data/generators/controller/controller_generator.rb +1 -1
  172. data/generators/controller/templates/test.rhtml +2 -1
  173. data/generators/model/templates/test.rhtml +1 -1
  174. data/generators/test/templates/test.rhtml +1 -1
  175. data/generators/view/templates/test.rhtml +1 -1
  176. data/jsdoc/templates/sproutcore/class.tmpl +241 -338
  177. data/jsdoc/templates/sproutcore/default.css +105 -155
  178. data/jsdoc/templates/sproutcore/index.tmpl +43 -8
  179. data/jsdoc/templates/sproutcore/publish.js +9 -4
  180. data/lib/sproutcore/build_tools/html_builder.rb +29 -13
  181. data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
  182. data/lib/sproutcore/bundle.rb +86 -25
  183. data/lib/sproutcore/jsdoc.rb +2 -0
  184. data/lib/sproutcore/version.rb +1 -1
  185. data/lib/sproutcore/view_helpers.rb +36 -3
  186. data/tasks/deployment.rake +1 -1
  187. metadata +69 -36
  188. data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
  189. data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
  190. data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
  191. data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
  192. data/clients/sc_docs/english.lproj/warning.rhtml +0 -6
  193. data/clients/sc_test_runner/english.lproj/warning.rhtml +0 -6
  194. data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
  195. data/frameworks/sproutcore/english.lproj/collections.css +0 -82
  196. data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
  197. data/frameworks/sproutcore/views/collection/collection_item.js +0 -36
  198. data/frameworks/sproutcore/views/collection/text_cell.js +0 -128
  199. data/frameworks/sproutcore/views/field.js +0 -214
  200. data/frameworks/sproutcore/views/workspace.js +0 -170
  201. data/generators/client/templates/english.lproj/controls.css +0 -0
  202. data/generators/framework/templates/english.lproj/body.css +0 -0
  203. data/generators/framework/templates/english.lproj/body.rhtml +0 -3
  204. data/generators/framework/templates/english.lproj/controls.css +0 -0
  205. data/lib/sproutcore/view_helpers/button_views.rb +0 -302
  206. data/lib/sproutcore/view_helpers/core_views.rb +0 -292
  207. data/lib/sproutcore/view_helpers/form_views.rb +0 -258
  208. data/lib/sproutcore/view_helpers/menu_views.rb +0 -94
@@ -1,6 +1,6 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
6
  require('foundation/path_module') ;
@@ -56,7 +56,10 @@ SC.Page = SC.Object.extend(
56
56
  if (value && (value instanceof Function) && (value.isOutlet)) {
57
57
  return null ;
58
58
  } else return value ;
59
- }
59
+ },
60
+
61
+ _insertBefore: function() {},
62
+ _rebuildChildNodes: function() {}
60
63
 
61
64
  }) ;
62
65
 
@@ -19,16 +19,17 @@ require('foundation/benchmark') ;
19
19
  SC.BENCHMARK_SELECTOR = NO ;
20
20
  NO_LIMIT = 10000 ;
21
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
- //
22
+ /**
23
+ PathModule is high-performance API for locating DOM nodes in your HTML
24
+ document. It's designed to be used by searching elements from a parent
25
+ node.
26
+
27
+ PathModule is patched into Prototypes Element.Methods, which means that
28
+ you can automatically access this API for any DOM element retrieved via
29
+ the $() operator. You can also mixin the PathModule api to your own
30
+ objects. Be sure to also have a property called rootElement that points to
31
+ the root DOM element you want to search.
32
+ */
32
33
  SC.PathModule = {
33
34
 
34
35
  $$func: function(func, levels, max, nest) {
@@ -1,6 +1,6 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
6
  require('Core') ;
@@ -8,7 +8,10 @@ require('foundation/object') ;
8
8
  require('foundation/input_manager');
9
9
 
10
10
  /**
11
- @class A responder is capable of responding to events such as mouse clicks and key presses.
11
+ @class
12
+
13
+ A responder is capable of responding to events such as mouse clicks and key
14
+ presses.
12
15
 
13
16
  All views are a type of responder, but you can extend this class yourself
14
17
  as well to implement your own responders if you need to.
@@ -1,12 +1,19 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
6
  require('foundation/object') ;
7
7
 
8
- // Routes makes it possible to load a location in the browser.
9
- SC.Routes = SC.Object.create({
8
+ /**
9
+ @class
10
+
11
+ Routes makes it possible to load a location in the browser.
12
+
13
+ @extends SC.Object
14
+ */
15
+ SC.Routes = SC.Object.create(
16
+ /** @scope SC.Routes.prototype */ {
10
17
 
11
18
  // set this property to your current app lication
12
19
  location: function(key,value) {
@@ -100,7 +107,7 @@ SC.Routes = SC.Object.create({
100
107
  if (!this._routes) this._routes = SC.Routes._Route.create() ;
101
108
  func = this._routes.functionForRoute(parts,params) ;
102
109
  if (func) func(params) ;
103
- else console.log('could not find route for: "'+route+'"') ;
110
+ //else console.log('could not find route for: "'+route+'"') ;
104
111
  },
105
112
 
106
113
 
@@ -135,8 +142,7 @@ SC.Routes = SC.Object.create({
135
142
  // create forward stack.
136
143
  this._forwardStack = [] ;
137
144
 
138
- this._boundChecker = this._checkWindowLocation.bind(this) ;
139
- this.timer = setTimeout(this._boundChecker,1000) ;
145
+ this.invokeLater(this._checkWindowLocation, 1000) ;
140
146
  },
141
147
 
142
148
  _checkWindowLocation: function() {
@@ -198,7 +204,7 @@ SC.Routes = SC.Object.create({
198
204
  this.gotoRoute(cloc) ;
199
205
  }
200
206
 
201
- this.timer = setTimeout(this._boundChecker,50) ;
207
+ this.invokeLater(this._checkWindowLocation, 50) ;
202
208
  },
203
209
 
204
210
  _setWindowLocation: function(loc) {
@@ -217,8 +223,7 @@ SC.Routes = SC.Object.create({
217
223
  // for IE.
218
224
  ie: {
219
225
  _setupHistory: function() {
220
- this._boundChecker = this._checkWindowLocation.bind(this) ;
221
- // this.timer = setTimeout(this._boundChecker,1000) ;
226
+ this.invokeLater(this._checkWindowLocation, 1000) ;
222
227
  },
223
228
 
224
229
  _checkWindowLocation: function() {
@@ -226,7 +231,7 @@ SC.Routes = SC.Object.create({
226
231
  var cloc = location.hash ;
227
232
  cloc = (cloc && cloc.length > 0) ? cloc.slice(1,cloc.length) : '' ;
228
233
  if (cloc != loc) this.set('location',(cloc) ? cloc : '') ;
229
- this.timer = setTimeout(this._boundChecker,100) ;
234
+ this.invokeLater(this._checkWindowLocation, 100) ;
230
235
  },
231
236
 
232
237
  _setWindowLocation: function(loc) {
@@ -242,8 +247,7 @@ SC.Routes = SC.Object.create({
242
247
  },
243
248
 
244
249
  _setupHistory: function() {
245
- this._boundChecker = this._checkWindowLocation.bind(this) ;
246
- this.timer = setTimeout(this._boundChecker,1000) ;
250
+ this.invokeLater(this._checkWindowLocation, 1000) ;
247
251
  },
248
252
 
249
253
  _checkWindowLocation: function() {
@@ -251,7 +255,7 @@ SC.Routes = SC.Object.create({
251
255
  var cloc = location.hash ;
252
256
  cloc = (cloc && cloc.length > 0) ? cloc.slice(1,cloc.length) : '' ;
253
257
  if (cloc != loc) this.set('location',(cloc) ? cloc : '') ;
254
- this.timer = setTimeout(this._boundChecker,100) ;
258
+ this.invokeLater(this._checkWindowLocation, 100) ;
255
259
  },
256
260
 
257
261
  _setWindowLocation: function(loc) {
@@ -1,21 +1,259 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
6
  require('Core') ;
7
7
 
8
- // RunLoop is used to manage deferred runs. It's lighter weight than setting
9
- // lots of timeouts.
8
+ /**
9
+ @class
10
+
11
+ The run loop provides a universal system for coordinating events within
12
+ your application. The run loop processes timers as well as pending
13
+ observer notifications within your application.
14
+
15
+ Typically you will not work with a run loop directly but instead user
16
+ SC.Timer objects and property observing to indirectly trigger actions on
17
+ the run loop. The only time you may need to work with the run loop is if
18
+ you implement a setTimeout or event handler yourself. In these cases, you
19
+ should begin and end your function handler with a call to beginRunLoop()
20
+ and endRunLoop(). This will give the run loop a chance to process any
21
+ pending events on your application.
22
+
23
+ h2. Using the Loop Start Time
24
+
25
+ Sometimes you need to schedule events such as timers and you want to make
26
+ sure all of the events you schedule occur at the same time. If you want to
27
+ keep items in sync you can't use Date.now() because that value will
28
+ increment as your code executes. Instead, you should get the loop start
29
+ time and use that. For example, if you want to schedule three timers to
30
+ repeat until 1 second, 2 seconds and 3 seconds from now you might do:
31
+
32
+ {{{
33
+ var t1 = SC.Timer.schedule({
34
+ interval: 100,
35
+ action: 'timer1',
36
+ repeats: YES,
37
+ until: SC.runLoop.get('startTime') + 1000 }) ;
38
+
39
+ var t2 = SC.Timer.schedule({
40
+ interval: 100,
41
+ action: 'timer1',
42
+ repeats: YES,
43
+ until: SC.runLoop.get('startTime') + 2000 }) ;
44
+
45
+ var t3 = SC.Timer.schedule({
46
+ interval: 100,
47
+ action: 'timer1',
48
+ repeats: YES,
49
+ until: SC.runLoop.get('startTime') + 3000 }) ;
50
+ }}}
51
+
52
+ This will ensure that each timer uses the exact same start time when
53
+ scheduling. This is critical if you want to keep animations in sync.
54
+
55
+ @extends SC.Object
56
+ @author Charles Jolley
57
+ @version 1.0
58
+ @since SproutCore 1.0
59
+ */
10
60
  SC.runLoop = SC.Object.create({
11
61
 
12
- schedule: function() {
13
- var args = $A(arguments) ;
14
- var obj = args.shift() ;
15
- var method = obj[args.shift()];
16
- var delay = args.pop() ;
17
- var func = function() { method.apply(obj, args); }
18
- return setTimeout(func, delay) ;
62
+ /**
63
+ Call this method whenver you begin executing code.
64
+
65
+ This is typically invoked automatically for you from event handlers and
66
+ the timeout handler. If you call setTimeout() or setInterval() yourself,
67
+ you may need to invoke this yourself.
68
+
69
+ @returns {void}
70
+ */
71
+ beginRunLoop: function() {
72
+ this._start = Date.now() ;
73
+ },
74
+
75
+ /**
76
+ Call this method whenever you are done executing code.
77
+
78
+ This is typically invoked automatically for you from event handlers and
79
+ the timeout handler. If you call setTimeout() or setInterval() yourself
80
+ you may need to invoke this yourself.
81
+
82
+ @returns {void}
83
+ */
84
+ endRunLoop: function() {
85
+ // flush any expired timers, possibly cancelling the timout.
86
+ this._flushExpiredTimers() ;
87
+ this._start = null ;
88
+ },
89
+
90
+ /**
91
+ The time the current run loop began executing.
92
+
93
+ All timers scheduled during this run loop will begin executing as if
94
+ they were scheduled at this time.
95
+
96
+ @type {Number}
97
+ @field
98
+ */
99
+ startTime: function() {
100
+ if (!this._start) this._start = Date.now();
101
+ return this._start ;
102
+ }.property(),
103
+
104
+ // timers are stored in the hash with a double linked list to keep them
105
+ // in order.
106
+ scheduleTimer: function(timer, runTime) {
107
+
108
+ if (!timer) throw "scheduleTimer requires a timer" ; // nothing to do
109
+
110
+ if (!this._timers) this._timers = {} ;
111
+ var guid = SC.guidFor(timer) ;
112
+
113
+ // either remove the timer record or create a new one and add it.
114
+ var t = this._timers[guid];
115
+ if (t) {
116
+ if (t.prev) t.prev.next = t.next ;
117
+ if (t.next) t.next.prev = t.prev ;
118
+ t.next = t.prev = null ;
119
+ t.at = runTime ;
120
+ } else {
121
+ t = this._timers[guid] = {
122
+ timer: timer,
123
+ at: runTime,
124
+ guid: guid,
125
+ next: null, prev: null
126
+ } ;
127
+ }
128
+
129
+ // now walk the chain to figure out where to insert the timer. If the
130
+ // timer goes at the front, also reschedule the next timeout.
131
+ var cur = this._next ;
132
+ if (!cur || cur.at > runTime) {
133
+ this._next = t ;
134
+ t.next = cur ;
135
+ if (cur) cur.prev = t.next ;
136
+ this._rescheduleTimeout() ;
137
+
138
+ } else {
139
+ // find the item to insert after
140
+ while(cur.next && cur.next.at <= runTime) cur = cur.next ;
141
+ t.next = cur.next ;
142
+ if (cur.next) cur.next.prev = t ;
143
+ cur.next = t ;
144
+ t.prev = cur ;
145
+ }
146
+ },
147
+
148
+ cancelTimer: function(timer) {
149
+
150
+ if (!timer) return ; //nothing to do
151
+
152
+ if (!this._timers) this._timers = {} ;
153
+ var guid = SC.guidFor(timer) ;
154
+ var t = this._timers[guid] ;
155
+
156
+ // if a timer record was found, remove it from the list.
157
+ // if timer was at the front, reschedule the timeout.
158
+ if (t) {
159
+ if (t.next) t.next.prev = t.prev ;
160
+ if (t.prev) t.prev.next = t.next ;
161
+ if (this._next === t) {
162
+ this._next = t.next ;
163
+ this._rescheduleTimeout() ;
164
+ }
165
+ t.next = t.prev = t.timer = null ; // clear objects
166
+ }
167
+ },
168
+
169
+ timerPausedStateDidChange: function(timer) {
170
+ this._rescheduleTimeout() ;
171
+ },
172
+
173
+ // determines the next time the timeout needs to trigger and reschedules
174
+ // if necessary. If you pass in the next timer to use, then it will be
175
+ // scheduled instead of searching the timers.
176
+ _rescheduleTimeout: function() {
177
+
178
+ // if we are currently flushing, don't do this since it will happen
179
+ // later anyway
180
+ if (this._flushing) return ;
181
+
182
+ if (!this._timers) this._timers = {} ;
183
+
184
+ // find next timer to trigger. If the first unpaused timer.
185
+ var rec = this._next ;
186
+ while(rec && rec.timer.get('isPaused')) rec = rec.next ;
187
+
188
+ // if no next timer was found, then cancel any timer.
189
+ if (!rec) {
190
+ this._timeoutAt = 0 ;
191
+ if (this._timeout) clearTimeout(this._timeout) ;
192
+ this._timeout = null ;
193
+
194
+ // determine if we need to reschedule
195
+ } else if ((this._timeoutAt === 0) || (rec.at !== this._timeoutAt)) {
196
+ if (this._timeout) clearTimeout(this._timeout) ;
197
+
198
+ var delay = Math.max(rec.at - Date.now(),0) ;
199
+ this._timeout = setTimeout(this._timeoutAction, delay) ;
200
+ this.timeoutAt = rec.at ;
201
+ }
202
+ },
203
+
204
+ // called when the timeout is executed. Find any timers that have
205
+ // expired and call them.
206
+ _timeoutAction: function() {
207
+ var rl = SC.runLoop;
208
+ rl._timeout = null; rl._timeoutAt = 0 ;
209
+ rl.beginRunLoop() ;
210
+ rl._flushExpiredTimers() ;
211
+ rl.endRunLoop() ;
212
+ },
213
+
214
+ // finds any timers that might have expired. This will also find the
215
+ // next timer to execute and reschedule it if needed.
216
+ _flushExpiredTimers: function() {
217
+ if (!this._timers) this._timers = {} ;
218
+ var now = this.get('startTime') ;
219
+ var max = now + 3000; // max time we are allowed to run timers
220
+
221
+ this._flushing = YES ;
222
+
223
+ // work down the list, do not fire a timer more than once per loop.
224
+ var fired = {} ;
225
+ var rec = this._next ;
226
+ while(rec && (rec.at <= now) && (Date.now() < max)) {
227
+
228
+ // if rec has been fired, go on to next one.
229
+ var guid = SC.guidFor(rec.timer) ;
230
+ if (fired[guid]) {
231
+ rec = rec.next;
232
+
233
+ // otherwise, remove rec from list and then fire it.
234
+ } else {
235
+ var next = rec.next;
236
+
237
+ if (this._next === rec) this._next = rec.next ;
238
+ if (rec.next) rec.next.prev = rec.prev ;
239
+ if (rec.prev) rec.prev.next = rec.next ;
240
+ delete this._timers[rec.guid] ;
241
+
242
+ fired[guid] = YES ;
243
+ if (rec.timer) rec.timer.fire() ;
244
+
245
+ // finish clean up.
246
+ rec.next = rec.prev = rec.timer = null ;
247
+ rec = next ;
248
+ }
249
+ }
250
+
251
+ this._flushing = NO ;
252
+
253
+ // schedule next timer if needed.
254
+ this._rescheduleTimeout() ;
19
255
  }
20
256
 
21
- }) ;
257
+
258
+ }) ;
259
+
@@ -1,6 +1,6 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
6
  require('Core') ;
@@ -1,9 +1,9 @@
1
1
  // ==========================================================================
2
2
  // SproutCore -- JavaScript Application Framework
3
- // copyright 2006-2007, Sprout Systems, Inc. and contributors.
3
+ // copyright 2006-2008, Sprout Systems, Inc. and contributors.
4
4
  // ==========================================================================
5
5
 
6
- require('foundation/array') ;
6
+ require('mixins/array') ;
7
7
 
8
8
  /**
9
9
  @class An unordered collection for keeping objects.
@@ -14,7 +14,7 @@ require('foundation/array') ;
14
14
  @extends SC.Object
15
15
 
16
16
  */
17
- SC.Set = SC.Object.extend(Enumerable,
17
+ SC.Set = SC.Object.extend(SC.Array,
18
18
  /** @scope SC.Set.prototype */
19
19
  {
20
20