sproutcore 0.9.14 → 0.9.15

Sign up to get free protection for your applications and to get access to all the features.
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
  },