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
@@ -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().