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
@@ -24,6 +24,7 @@ until you call commitChanges().
24
24
  SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
25
25
  /** @scope SC.ArrayController.prototype */
26
26
  {
27
+
27
28
  /**
28
29
  If YES the will return controllers for content objects.
29
30
 
@@ -44,23 +45,113 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
44
45
  arrangedObjects: function() { return this; }.property('content'),
45
46
 
46
47
  /**
47
- The array content that is being managed by the controller.
48
- @field
48
+ The content array managed by this controller.
49
+
50
+ In general you can treat an instance of ArrayController as if it were
51
+ the array held in this property. Any changes you make to the controller
52
+ that are not specifically implemented in the controller will pass through
53
+ to the Array.
54
+
55
+ Also if you set commitsChangesImmediately to false, the controller will
56
+ buffer changes against this.
57
+
58
+ @property
49
59
  @type {Array}
50
60
  */
51
61
  content: null,
52
62
  contentBindingDefault: SC.Binding.Multiple,
63
+
64
+ /**
65
+ Set to true if the controller has any content, even an empty array.
66
+ */
67
+ hasContent: function() {
68
+ return this.get('content') != null ;
69
+ }.property('content'),
53
70
 
54
71
  /**
55
72
  Set to true if you want objects removed from the array to also be
56
73
  deleted. This is a convenient way to manage lists of items owned
57
74
  by a parent record object.
58
75
 
76
+ Note that even if this is set to NO, calling destroyObject() instead of
77
+ removeObject() will still destroy the object in question as well as
78
+ removing it from the parent array.
79
+
59
80
  @field
60
81
  @type {Boolean}
61
82
  */
62
83
  destroyOnRemoval: NO,
84
+
85
+ /**
86
+ Defines the default class to use when creating new content.
63
87
 
88
+ This property should either contains a class or a string that resolves
89
+ to a class that responds to the newRecord() method.
90
+
91
+ @property
92
+ @type {Class}
93
+ */
94
+ exampleContentObject: null,
95
+
96
+ /**
97
+ Creates a new record instance and adds it to the end of the current array.
98
+
99
+ This method works just like insertNewObjectAt() but always appends.
100
+
101
+ @param attributes {Hash} optional hash of attributes to pass to the new obejct.
102
+ @param objectType {Class} optional class of object to create.
103
+ @returns {Object} the newly created object (also added to the array)
104
+ */
105
+ newObject: function(attributes, objectType) {
106
+ return this.insertNewObjectAt(null, attributes, objectType) ;
107
+ },
108
+
109
+ /**
110
+ Creates a new content object and inserts it at the passed index or appends
111
+ it at the end of the array if you pass null.
112
+
113
+ This method takes an optional hash of attributes which will be set on
114
+ the new record. You can also pass an optional objectType. If you do
115
+ not pass the objectType, you must instead set the exampleContentObject to
116
+ the class of the object you want to use. The object can be of any type
117
+ but it must respond to the newRecord() method.
118
+
119
+ Objects created using this method will be destroyed automatically if you
120
+ have set commitsChangesImmediately to false and call discardChanges().
121
+
122
+ @param index {Number} the index to insert at or null to append.
123
+ @param attributes {Hash} optional hash of attributes to pass to the new obejct.
124
+ @param objectType {Class} optional class of object to create.
125
+ @returns {Object} the newly created object (also added to the array)
126
+ */
127
+ insertNewObjectAt: function(index, attributes, objectType) {
128
+
129
+ // compute the objectType
130
+ if (!objectType) objectType = this.get('exampleContentObject') ;
131
+ if ($type(objectType) === T_STRING) {
132
+ objectType = SC.Object.objectForPropertyPath(objectType) ;
133
+ }
134
+ if (objectType == null) {
135
+ throw "Invalid object type was provided" ;
136
+ }
137
+
138
+ if ($type(objectType.newObject) !== T_FUNCTION) {
139
+ throw "content object type does not support newRecord()" ;
140
+ }
141
+
142
+ // Create a new object...
143
+ var obj = objectType.newObject(attributes) ;
144
+ if (!this._createdObjects) this._createdObjects = [] ;
145
+ this._createdObjects.push(obj) ; // save for discard...
146
+
147
+ // Add to array.
148
+ if (index) {
149
+ this.insertAt(index, obj) ;
150
+ } else this.pushObject(obj) ;
151
+
152
+ return obj ;
153
+ },
154
+
64
155
  /**
65
156
  Watches changes to the content property updates the contentClone.
66
157
  @private
@@ -94,7 +185,7 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
94
185
 
95
186
  this.beginPropertyChanges();
96
187
  this.contentCloneReset();
97
- this.arrayContentDidChange() ;
188
+ this.enumerableContentDidChange() ;
98
189
  this.notifyPropertyChange('length') ;
99
190
  this.updateSelectionAfterContentChange();
100
191
  this.endPropertyChanges() ;
@@ -140,8 +231,13 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
140
231
 
141
232
  // in case the passed objects are controllers, convert to source objects.
142
233
  var copyIdx = objects.length ;
143
- var sourceObjects = [] ;
144
- while(--copyIdx >= 0) sourceObjects[copyIdx] = this._sourceObjectFor(objects[copyIdx]) ;
234
+ var sourceObjects = objects ;
235
+ if (copyIdx > 0) {
236
+ sourceObjects = [] ;
237
+ while(--copyIdx >= 0) {
238
+ sourceObjects[copyIdx] = this._sourceObjectFor(objects[copyIdx]) ;
239
+ }
240
+ }
145
241
 
146
242
  // create clone of content array if needed
147
243
  var contentClone = this.get('contentClone') ;
@@ -165,17 +261,16 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
165
261
  contentClone.replace(idx, amt, sourceObjects);
166
262
 
167
263
  this.editorDidChange() ;
168
- this.arrayContentDidChange();
264
+ this.enumerableContentDidChange();
169
265
  this.updateSelectionAfterContentChange();
170
266
 
171
267
  return this;
172
268
  },
269
+
173
270
  /**
174
- * SC.Array interface implimentation.
175
- *
176
- * @param {Number} idx
177
- * The index of the item to return. If idx exceeds the current length,
178
- * return null.
271
+ SC.Array interface implimentation.
272
+ @param idx {Number} The index of the item to return. If idx exceeds the
273
+ current length, return null.
179
274
  */
180
275
  objectAt: function(idx) {
181
276
  var obj = this._getSourceContent() ;
@@ -183,9 +278,9 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
183
278
  return this._objectControllerFor(obj) ;
184
279
  },
185
280
  /**
186
- * SC.Array interface implimentation.
187
- * @field
188
- * @type {integer}
281
+ SC.Array interface implimentation.
282
+ @property
283
+ @type {integer}
189
284
  */
190
285
  length: function( key, value ) {
191
286
  var ret = this._getSourceContent() ;
@@ -222,14 +317,15 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
222
317
 
223
318
 
224
319
  // apply all the changes made to the clone
225
- var changelog = this._changelog || [] ;
226
- for(var idx=0;idx<changelog.length;idx++) {
227
- var change = changelog[idx];
228
- content.replace(change.idx, change.amt, change.objects) ;
320
+ if (this._changelog) {
321
+ var changelog = this._changelog ;
322
+ var max = changelog.length;
323
+ for(var idx=0;idx<max;idx++) {
324
+ var change = changelog[idx];
325
+ content.replace(change.idx, change.amt, change.objects) ;
326
+ }
327
+ this._changelog.length = 0 ; // reset changelog
229
328
  }
230
-
231
- // done, flush the changelog
232
- this._changelog = [] ;
233
329
 
234
330
  // finally, destroy any removed objects if necessary. Make
235
331
  // sure the objects have not been re-added before doing this.
@@ -241,9 +337,12 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
241
337
  obj.destroy() ;
242
338
  }
243
339
  }
244
- this._deletions = [] ; // clear array
340
+ this._deletions.length = 0; // clear array
245
341
  }
246
342
 
343
+ // changes commited, clear any created objects from the internal array
344
+ if (this._createdObjects) this._createdObjects.length = 0 ;
345
+
247
346
  // finish commiting changes.
248
347
  if (content.endPropertyChanges) content.endPropertyChanges();
249
348
  if (content.commitChanges) ret = content.commitChanges();
@@ -262,6 +361,18 @@ SC.ArrayController = SC.Controller.extend(SC.Array, SC.SelectionSupport,
262
361
  {
263
362
  this.contentCloneReset();
264
363
  this.editorDidClearChanges();
364
+
365
+ // if any objects were created before the commit, destroy the objects
366
+ // and reset the array.
367
+ if (this._createdObjects && this._createdObjects.length > 0) {
368
+ var idx = this._createdObjects.length ;
369
+ while(--idx >= 0) {
370
+ var obj = this._createdObjects[idx] ;
371
+ if ($type(obj.destroy) === T_FUNCTION) obj.destroy() ;
372
+ }
373
+ this._createdObjects.length = 0 ;
374
+ }
375
+
265
376
  return true;
266
377
  },
267
378
 
@@ -17,8 +17,7 @@ require('controllers/object') ;
17
17
  @extends SC.ObjectController
18
18
  */
19
19
  SC.CollectionController = SC.ObjectController.extend(SC.SelectionSupport,
20
- /** @scope SC.CollectionController.prototype */
21
- {
20
+ /** @scope SC.CollectionController.prototype */ {
22
21
 
23
22
  // ...................................
24
23
  // PROPERTIES
@@ -106,7 +105,7 @@ SC.CollectionController = SC.ObjectController.extend(SC.SelectionSupport,
106
105
  var content = this.get('content') ;
107
106
  if (!content || !this.get('canEditCollection')) return ; // only if allowed
108
107
  try {
109
- objects = $A(arguments).flatten() ;
108
+ objects = SC.$A(arguments).flatten() ;
110
109
  if (content.addRecords) {
111
110
  content.addRecords(objects) ;
112
111
  this.set('selection',(objects) ? objects : []) ;
@@ -127,7 +126,7 @@ SC.CollectionController = SC.ObjectController.extend(SC.SelectionSupport,
127
126
  var content = this.get('content') ;
128
127
  if (!content || !this.get('canEditCollection')) return ; // only if allowed
129
128
  try {
130
- objects = $A(arguments).flatten() ;
129
+ objects = SC.$A(arguments).flatten() ;
131
130
  if (content.removeRecords) {
132
131
  var rec = content.removeRecords(objects) ;
133
132
  var sel = (this.get('selection') || []).without(objects) ;
@@ -192,7 +191,7 @@ SC.CollectionController = SC.ObjectController.extend(SC.SelectionSupport,
192
191
  // potentially the selection.
193
192
  _recordsObserver: function(target,key,value) {
194
193
  var old = this.get('arrangedObjects') ;
195
- value = Array.asArray(target.get(key)) ;
194
+ value = Array.from(target.get(key)) ;
196
195
 
197
196
  this.set('arrangedObjects',value.slice()) ;
198
197
 
@@ -19,8 +19,7 @@ require('controllers/controller') ;
19
19
  @extends SC.Controller
20
20
  */
21
21
  SC.ObjectController = SC.Controller.extend(
22
- /** @scope SC.ObjectController.prototype */
23
- {
22
+ /** @scope SC.ObjectController.prototype */ {
24
23
 
25
24
  // ...............................
26
25
  // PROPERTIES
@@ -57,6 +56,13 @@ SC.ObjectController = SC.Controller.extend(
57
56
  */
58
57
  hasMultipleContent: false,
59
58
 
59
+ /**
60
+ Set to true if the controller has any content, even an empty array.
61
+ */
62
+ hasContent: function() {
63
+ return this.get('content') != null ;
64
+ }.property('content'),
65
+
60
66
  /**
61
67
  Set this property to true and multiple content will be treated like a null
62
68
  value. This will only impact use of get() and set().