sproutcore 0.9.14 → 0.9.15

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 (61) hide show
  1. data/History.txt +43 -0
  2. data/Manifest.txt +12 -3
  3. data/bin/sc-build +19 -3
  4. data/bin/sc-install +5 -0
  5. data/bin/sc-remove +5 -0
  6. data/bin/sc-update +5 -0
  7. data/frameworks/prototype/prototype.js +267 -230
  8. data/frameworks/sproutcore/HISTORY +281 -135
  9. data/frameworks/sproutcore/controllers/array.js +133 -22
  10. data/frameworks/sproutcore/controllers/collection.js +4 -5
  11. data/frameworks/sproutcore/controllers/object.js +8 -2
  12. data/frameworks/sproutcore/core.js +361 -159
  13. data/frameworks/sproutcore/{foundation → debug}/unittest.js +3 -3
  14. data/frameworks/sproutcore/english.lproj/detect-browser +1 -1
  15. data/frameworks/sproutcore/english.lproj/theme.css +2 -2
  16. data/frameworks/sproutcore/foundation/application.js +6 -1
  17. data/frameworks/sproutcore/foundation/benchmark.js +37 -11
  18. data/frameworks/sproutcore/foundation/date.js +1 -1
  19. data/frameworks/sproutcore/foundation/enumerator.js +105 -0
  20. data/frameworks/sproutcore/foundation/object.js +19 -20
  21. data/frameworks/sproutcore/foundation/responder.js +1 -1
  22. data/frameworks/sproutcore/foundation/set.js +164 -57
  23. data/frameworks/sproutcore/foundation/string.js +151 -47
  24. data/frameworks/sproutcore/foundation/utils.js +84 -3
  25. data/frameworks/sproutcore/lib/collection_view.rb +1 -0
  26. data/frameworks/sproutcore/license.js +28 -0
  27. data/frameworks/sproutcore/mixins/array.js +73 -209
  28. data/frameworks/sproutcore/mixins/delegate_support.js +1 -1
  29. data/frameworks/sproutcore/mixins/enumerable.js +1006 -0
  30. data/frameworks/sproutcore/mixins/observable.js +153 -84
  31. data/frameworks/sproutcore/mixins/selection_support.js +13 -1
  32. data/frameworks/sproutcore/models/record.js +74 -27
  33. data/frameworks/sproutcore/models/store.js +7 -3
  34. data/frameworks/sproutcore/server/rails_server.js +82 -0
  35. data/frameworks/sproutcore/server/rest_server.js +178 -0
  36. data/frameworks/sproutcore/{foundation → server}/server.js +101 -48
  37. data/frameworks/sproutcore/tests/core/guidFor.rhtml +114 -0
  38. data/frameworks/sproutcore/tests/foundation/array.rhtml +6 -7
  39. data/frameworks/sproutcore/tests/foundation/set.rhtml +254 -0
  40. data/frameworks/sproutcore/tests/mixins/enumerable.rhtml +421 -0
  41. data/frameworks/sproutcore/tests/mixins/observable.rhtml +127 -0
  42. data/frameworks/sproutcore/tests/models/model.rhtml +23 -22
  43. data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +2 -2
  44. data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +112 -109
  45. data/frameworks/sproutcore/tests/views/view/frame.rhtml +91 -88
  46. data/frameworks/sproutcore/validators/date.js +1 -7
  47. data/frameworks/sproutcore/views/collection/collection.js +7 -2
  48. data/frameworks/sproutcore/views/list_item.js +141 -3
  49. data/frameworks/sproutcore/views/split.js +14 -11
  50. data/frameworks/sproutcore/views/view.js +9 -6
  51. data/lib/sproutcore/build_tools/html_builder.rb +19 -3
  52. data/lib/sproutcore/build_tools/resource_builder.rb +9 -3
  53. data/lib/sproutcore/bundle.rb +21 -0
  54. data/lib/sproutcore/bundle_manifest.rb +64 -20
  55. data/lib/sproutcore/helpers/capture_helper.rb +2 -2
  56. data/lib/sproutcore/library.rb +33 -9
  57. data/lib/sproutcore/merb/bundle_controller.rb +16 -5
  58. data/lib/sproutcore/version.rb +1 -1
  59. data/lib/sproutcore/view_helpers.rb +1 -1
  60. data/{sc-config.rb → sc-config} +5 -2
  61. metadata +24 -5
@@ -3,10 +3,7 @@
3
3
  // copyright 2006-2008, Sprout Systems, Inc. and contributors.
4
4
  // ==========================================================================
5
5
 
6
- require('mixins/observable');
7
-
8
- // Make Arrays observable
9
- Object.extend(Array.prototype, SC.Observable) ;
6
+ require('mixins/enumerable') ;
10
7
 
11
8
  SC.OUT_OF_RANGE_EXCEPTION = "Index out of range" ;
12
9
 
@@ -17,6 +14,17 @@ SC.OUT_OF_RANGE_EXCEPTION = "Index out of range" ;
17
14
  picked up by the Array class as well as other controllers, etc. that want to
18
15
  appear to be arrays.
19
16
 
17
+ Unlike SC.Enumerable, this mixin defines methods specifically for
18
+ collections that provide index-ordered access to their contents. When you
19
+ are designing code that needs to accept any kind of Array-like object, you
20
+ should use these methods instead of Array primitives because these will
21
+ properly notify observers of changes to the array.
22
+
23
+ Although these methods are efficient, they do add a layer of indirection to
24
+ your application so it is a good idea to use them only when you need the
25
+ flexibility of using both true JavaScript arrays and "virtual" arrays such
26
+ as controllers and collections.
27
+
20
28
  You can use the methods defined in this module to access and modify array
21
29
  contents in a KVO-friendly way. You can also be notified whenever the
22
30
  membership if an array changes by observing the "[]" property.
@@ -24,6 +32,11 @@ SC.OUT_OF_RANGE_EXCEPTION = "Index out of range" ;
24
32
  To support SC.Array in your own class, you must override two
25
33
  primitives to use it: replace() and objectAt().
26
34
 
35
+ Note that the SC.Array mixin also incorporates the SC.Enumerable mixin. All
36
+ SC.Array-like objects are also enumerable.
37
+
38
+ @extends SC.Enumerable
39
+ @since SproutCore 0.9.0
27
40
  */
28
41
  SC.Array = {
29
42
 
@@ -38,7 +51,7 @@ SC.Array = {
38
51
  /**
39
52
  This is one of the primitves you must implement to support SC.Array. You
40
53
  should replace amt objects started at idx with the objects in the passed
41
- array. You should also call this.arrayContentDidChange() ;
54
+ array. You should also call this.enumerableContentDidChange() ;
42
55
 
43
56
  @param {Number} idx
44
57
  Starting index in the array to replace. If idx >= length, then append to
@@ -72,24 +85,6 @@ SC.Array = {
72
85
  if (idx >= this.get('length')) return undefined;
73
86
  return this.get(idx);
74
87
  },
75
-
76
- // this is required to support the enumerable options. Override with your
77
- // own method if you prefer.
78
- _each: function(iterator) {
79
- var len ;
80
- for (var i = 0, len = this.get('length'); i < len; i++)
81
- iterator(this.objectAt(i));
82
- },
83
-
84
- /**
85
- When you implement replace(), be sure to call this method whenever the
86
- membership of your array changes. This will make sure users are properly
87
- notified.
88
- */
89
- arrayContentDidChange: function() {
90
- var kvo = (this._kvo) ? this._kvo().changes : '(null)';
91
- this.notifyPropertyChange('[]') ;
92
- },
93
88
 
94
89
  /**
95
90
  @field []
@@ -97,6 +92,8 @@ SC.Array = {
97
92
  This is the handler for the special array content property. If you get
98
93
  this property, it will return this. If you set this property it a new
99
94
  array, it will replace the current content.
95
+
96
+ This property overrides the default property defined in SC.Enumerable.
100
97
  */
101
98
  '[]': function(key, value) {
102
99
  if (value !== undefined) {
@@ -196,206 +193,73 @@ SC.Array = {
196
193
  if (loc != this.get('length')) return false ;
197
194
 
198
195
  while(--loc >= 0) {
199
- if (ary.objectAt(loc) != this.objectAt(loc)) return false ;
196
+ if (!SC.isEqual(ary.objectAt(loc), this.objectAt(loc))) return false ;
200
197
  }
201
198
  return true ;
202
- },
203
-
204
- /**
205
- Invoke the passed method and arguments on the member elements as long as
206
- the value returned is the first argument.
207
-
208
- @param {Object} retValue the expected return value
209
- @param {String} methodName the method to call
210
- @returns {Object} the return value of the last time the method was
211
- invoked.
212
- */
213
- invokeWhile: function(retValue, methodName) {
214
- var ret ;
215
- var args = $A(arguments) ;
216
- retValue = args.shift() ;
217
- methodName = args.shift() ;
218
-
219
- try {
220
- this._each(function(item) {
221
- var func = (item) ? item[methodName] : null ;
222
- ret = func.apply(item, args) ;
223
- if (ret != retValue) throw $break ;
224
- });
225
- } catch (e) {
226
- if (e != $break) throw e ;
227
- }
228
- return ret ;
229
199
  }
230
-
200
+
231
201
  } ;
232
202
 
233
- // All arrays have the SC.Array mixin. Do this before we add the
234
- // enumerable methods since Arrays are already enumerable.
235
- Object.extend(Array.prototype, SC.Array) ;
203
+ // Add SC.Array to the built-in array before we add SC.Enumerable to SC.Array
204
+ // since built-in Array's are already enumerable.
205
+ SC.mixin(Array.prototype, SC.Array) ;
206
+ SC.Array = SC.mixin({}, SC.Enumerable, SC.Array) ;
236
207
 
237
- // Now make SC.Array enumerable and add other array method we did not want to
238
- // override in Array itself.
239
- Object.extend(SC.Array, Enumerable) ;
240
- Object.extend(SC.Array, {
241
- /**
242
- Returns a new array that is a slice of the receiver. This implementation
243
- uses the observable array methods to retrieve the objects for the new slice.
244
-
245
- @param beginIndex {Integer} (Optional) index to begin slicing from. Default: 0
246
- @param endIndex {Integer} (Optional) index to end the slice at. Default: 0
247
- */
248
- slice: function(beginIndex, endIndex) {
249
- var ret = [];
250
- var length = this.get('length') ;
251
- if (beginIndex == null) beginIndex = 0 ;
252
- if ((endIndex == null) || (endIndex > length)) endIndex = length ;
253
- while(beginIndex < endIndex) ret[ret.length] = this.objectAt(beginIndex++) ;
254
- return ret ;
255
- }
208
+ // Add any extra methods to SC.Array that are native to the built-in Array.
209
+ /**
210
+ Returns a new array that is a slice of the receiver. This implementation
211
+ uses the observable array methods to retrieve the objects for the new
212
+ slice.
256
213
 
257
- }) ;
258
-
259
- // ........................................................
260
- // A few basic enhancements to the Array class.
261
- // These methods add support for the SproutCore replace() method as well as
262
- // optimizing certain enumerable methods.
214
+ @param beginIndex {Integer} (Optional) index to begin slicing from.
215
+ @param endIndex {Integer} (Optional) index to end the slice at.
216
+ @returns {Array} New array with specified slice
217
+ */
218
+ SC.Array.slice = function(beginIndex, endIndex) {
219
+ var ret = [];
220
+ var length = this.get('length') ;
221
+ if (beginIndex == null) beginIndex = 0 ;
222
+ if ((endIndex == null) || (endIndex > length)) endIndex = length ;
223
+ while(beginIndex < endIndex) ret[ret.length] = this.objectAt(beginIndex++) ;
224
+ return ret ;
225
+ } ;
226
+
227
+
228
+ // ......................................................
229
+ // ARRAY SUPPORT
263
230
  //
264
- Object.extend(Array.prototype, {
265
-
266
- // primitive for array support.
267
- replace: function(idx, amt, objects) {
268
- if (!objects || objects.length == 0) {
269
- this.splice(idx, amt) ;
270
- } else {
271
- var args = [idx, amt].concat(objects) ;
272
- this.splice.apply(this,args) ;
273
- }
274
- this.arrayContentDidChange() ;
275
- return this ;
276
- },
231
+ // Implement the same enhancements on Array. We use specialized methods
232
+ // because working with arrays are so common.
233
+ (function() {
234
+ SC.mixin(Array.prototype, {
235
+
236
+ // primitive for array support.
237
+ replace: function(idx, amt, objects) {
238
+ if (!objects || objects.length == 0) {
239
+ this.splice(idx, amt) ;
240
+ } else {
241
+ var args = [idx, amt].concat(objects) ;
242
+ this.splice.apply(this,args) ;
243
+ }
244
+ this.enumerableContentDidChange() ;
245
+ return this ;
246
+ },
277
247
 
278
- // These are faster implementations of the iterations defined by prototype.
279
- // The iterators there are cool but they consume large numbers of stack
280
- // frames. These are API compatible, but much faster because they duplicate
281
- // code instead of calling a bunch of common methods.
282
-
283
- each: function(iterator) {
284
- try {
285
- for(var index=0;index<this.length;index++) {
286
- var item = this[index] ;
287
- iterator.call(item,item,index) ;
248
+ // If you ask for an unknown property, then try to collect the value
249
+ // from member items.
250
+ unknownProperty: function(key, value) {
251
+ var ret = this.reducedProperty(key, value) ;
252
+ if (ret === undefined) {
253
+ ret = (value === undefined) ? this.invoke('get', key) : null ;
288
254
  }
289
- } catch (e) {
290
- if (e != $break) throw e ;
291
- }
292
- return this ;
293
- },
294
-
295
- invoke: function(iterator) {
296
- var args = $A(arguments) ;
297
- var methodName = args.shift() ;
298
- var ret = [] ;
299
- try {
300
- for(var index=0;index<this.length;index++) {
301
- var item = this[index] ;
302
- ret.push(item[methodName].apply(item,args)) ;
303
- } ;
304
- } catch (e) {
305
- if (e != $break) throw e ;
255
+ return ret ;
306
256
  }
307
- return ret ;
308
- },
309
-
310
- /*
311
- Invoke the passed method and arguments on the member elements as long as
312
- the value returned is the first argument.
313
257
 
314
- @param {Object} retValue the expected return value
315
- @param {String} methodName the method to call
316
- @returns {Object} the return value of the last time the method was
317
- invoked.
318
- */
319
- invokeWhile: function(retValue, methodName) {
320
- var ret ;
321
- var args = $A(arguments) ;
322
- retValue = args.shift() ;
323
- methodName = args.shift() ;
324
-
325
- try {
326
- for(var index=0; index < this.length; index++) {
327
- var item = this[index] ;
328
- var func = (item) ? item[methodName] : null ;
329
- ret = func.apply(item, args) ;
330
- if (ret != retValue) return retValue ;
331
- }
332
- } catch (e) {
333
- if (e != $break) throw e ;
334
- }
335
- return ret ;
336
- },
258
+ }) ;
337
259
 
338
- map: function(iterator) {
339
- var ret = [] ;
340
- try {
341
- for(var index=0;index<this.length;index++) {
342
- var item = this[index] ;
343
- ret.push((iterator || Prototype.K).call(item,item,index)) ;
344
- } ;
345
- } catch (e) {
346
- if (e != $break) throw e ;
347
- }
348
- return ret ;
349
- },
350
-
351
-
352
- // If you ask for an unknown property, then try to collect the value
353
- // from member items.
354
- unknownProperty: function(key, value) {
355
- if (value !== undefined) return null ;
356
- return this.invoke('get', key) ;
357
- }
358
-
359
- }) ;
360
-
361
- Array.prototype.collect = Array.prototype.map ;
362
-
260
+ })() ;
363
261
 
364
262
  // Returns the passed item as an array. If the item is already an array,
365
263
  // it is returned as is. If it is not an array, it is placed into one. If
366
264
  // it is null, an empty array is returned.
367
- Array.asArray = function (array) {
368
- if(array &&
369
- ((array.length === undefined) || ($type(array) == T_FUNCTION))) {
370
- return [array];
371
- }
372
- return (array) ? array : [] ;
373
- };
374
-
375
- // Alias for asArray
376
- Array.from = Array.asArray ;
377
-
378
- // Map added array methods to other enumerables
379
- Object.extend(Enumerable, {
380
-
381
- invokeWhile: function(retValue, methodName) {
382
- var ret ;
383
- var args = $A(arguments) ;
384
- retValue = args.shift() ;
385
- methodName = args.shift() ;
386
-
387
- try {
388
- var obj = this ;
389
- this._each(function(item) {
390
- var func = (item) ? item[methodName] : null ;
391
- ret = func.apply(item, args) ;
392
- if (ret != retValue) $break ;
393
- }) ;
394
- } catch (e) {
395
- if (e != $break) throw e ;
396
- }
397
- return ret ;
398
- }
399
-
400
- }) ;
401
-
265
+ Array.from = SC.$A ;
@@ -47,7 +47,7 @@ SC.DelegateSupport = {
47
47
  @returns value returned by delegate
48
48
  */
49
49
  invokeDelegateMethod: function(delegate, methodName, args) {
50
- args = $A(arguments); args = args.slice(2, args.length) ;
50
+ args = SC.$A(arguments); args = args.slice(2, args.length) ;
51
51
  if (!delegate || !delegate[methodName]) delegate = this ;
52
52
  return delegate[methodName].apply(delegate, args) ;
53
53
  },