sproutcore 1.4.2-java → 1.4.3-java

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 (42) hide show
  1. data/CHANGELOG +11 -0
  2. data/Rakefile +27 -436
  3. data/VERSION.yml +1 -1
  4. data/lib/frameworks/sproutcore/CHANGELOG +32 -2
  5. data/lib/frameworks/sproutcore/frameworks/animation/core.js +1 -1
  6. data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +8 -2
  7. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/nested_records/nested_record.js +42 -2
  8. data/lib/frameworks/sproutcore/frameworks/debug/invoke_once_last_debugging.js +7 -12
  9. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/radio/ui.js +22 -1
  10. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +1 -1
  11. data/lib/frameworks/sproutcore/frameworks/desktop/views/list.js +6 -2
  12. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +1 -1
  13. data/lib/frameworks/sproutcore/frameworks/desktop/views/radio.js +38 -10
  14. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroller.js +8 -8
  15. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +1 -1
  16. data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +12 -5
  17. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/button.js +3 -3
  18. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +14 -9
  19. data/lib/frameworks/sproutcore/frameworks/foundation/system/datetime.js +3 -1
  20. data/lib/frameworks/sproutcore/frameworks/foundation/system/root_responder.js +25 -17
  21. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/beginEditing.js +46 -36
  22. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/validatable/ui.js +1 -1
  23. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/datetime.js +5 -0
  24. data/lib/frameworks/sproutcore/frameworks/foundation/tests/validators/not_empty.js +56 -0
  25. data/lib/frameworks/sproutcore/frameworks/foundation/validators/date_time.js +1 -1
  26. data/lib/frameworks/sproutcore/frameworks/foundation/validators/not_empty.js +7 -3
  27. data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +1 -1
  28. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +1 -1
  29. data/lib/frameworks/sproutcore/frameworks/media/views/controls.js +1 -1
  30. data/lib/frameworks/sproutcore/frameworks/media/views/media_slider.js +1 -1
  31. data/lib/frameworks/sproutcore/frameworks/media/views/mini_controls.js +1 -1
  32. data/lib/frameworks/sproutcore/frameworks/media/views/simple_controls.js +1 -1
  33. data/lib/frameworks/sproutcore/frameworks/media/views/video.js +1 -1
  34. data/lib/frameworks/sproutcore/frameworks/runtime/private/observer_set.js +1 -1
  35. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +18 -23
  36. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +13 -0
  37. data/lib/sproutcore/builders/base.rb +4 -4
  38. data/lib/sproutcore/builders/javascript.rb +0 -7
  39. data/lib/sproutcore/builders/stylesheet.rb +0 -7
  40. data/lib/sproutcore/rack/proxy.rb +28 -13
  41. metadata +4 -4
  42. data/DISTRIBUTION.yml +0 -20
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 4
4
- :patch: 2
4
+ :patch: 3
5
5
  :digest: e038ba5746bb757cd0ff2391828c5f03496fbb64
6
6
  :dist:
7
7
  frameworks/sproutcore: 7174adeb47aa0930c95ddae79e2c9cf042fded45
@@ -1,10 +1,40 @@
1
- *SproutCore 1.4.2 (October, 1 2010)*
1
+ *SproutCore 1.4.3 (October 19, 2010)*
2
+
3
+ * Send a warning to the console when using SC.RecordArray#indexOf or SC.RecordArray#lastIndexOf and providing an object that is
4
+ * Applied fix to the findClassNames function so that class names can be detected when using SproutCore in IE 7 and 8.
5
+ * SC.ObserverSet.add was being overloaded in debug mode by a version that mucked up passing along a context with addObserver. T
6
+ * rendering of select field will now honor isEnabled, ensuring that the control is disabled in the markup if not enabled in cod
7
+ * adding an observer that monitors the objects content (and not just the reference) so that any changes to the content will upd
8
+ * NotEmpty validator would not validate 0 as a non-empty number
9
+ * Spelling fixes in api doc
10
+ * Fix spelling in license header
11
+ * LabelView: allow inline editing of numbers like 0
12
+ * Refactor duplicated code into a function
13
+ * Made errors with not correctly initialized caches obvious to find.
14
+ * Add same guard clause as in insertTab
15
+ * Fix tabbing in the previous direction as well
16
+ * Make tabbing between inline text fields work
17
+ * Make SC.Animatable not crash when it lacks a parent view.
18
+ * Changed SC.Button mixin to support content objects that do not have get
19
+ * Fixed issue with SC.ScrollerView not properly updating its element's class names, e.g., if controlsHidden changed to false, t
20
+ * SC.ScrollerView's thumbs now default to their position -- solves an issue where going back to a view that had already been sc
21
+ * Explicitly check falsity of isReady in SC._object_className so searching for class names in tests work
22
+ * SC.ListItemView checks rightIcon property when determining if click occurred within it
23
+ * For radio buttons with horizontal layoutDirection, added itemWidthKey for custom widths -- fixes Github Issue #27
24
+ * These tests fail because the store status for the child record is only updated when you 'get' the status of the child record.
25
+ * return null instead of undefined from select field view getFieldValue when empty item selected.
26
+ * Sanity check in CollectionView item removal
27
+ * Fixed SC root responder's mousemove function so that last hovered views are exited first before other views are entered
28
+ * Fixes passing contexts with addObserver.
29
+ * Make sure a bad DateTime.parse() doesn't mess up future parses
30
+
31
+ *SproutCore 1.4.2 (October 1, 2010)*
2
32
 
3
33
  * Fixes a DateTime .get('lastMonday') bug
4
34
  * default to using ISO 8601 format for time parsing if none is specified
5
35
  * Allow SelectFieldView to obtain focus if the user presses TAB key from previous field.
6
36
  * Fixed typo
7
37
 
8
- *SproutCore 1.4.1 (September, 21 2010)*
38
+ *SproutCore 1.4.1 (September 21, 2010)*
9
39
 
10
40
  * Update the X-SproutCore-Version header to 1.4 [MO]
@@ -279,7 +279,7 @@ SC.Animatable = {
279
279
  this.layout = start;
280
280
 
281
281
  // get our frame and parent's frame
282
- var p = this.computeParentDimensions();
282
+ var p = this.computeParentDimensions(this.get("frame"));
283
283
  var f = this.computeFrameWithParentFrame(p);
284
284
 
285
285
  // set back to target
@@ -223,7 +223,10 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
223
223
  @returns {Number} index
224
224
  */
225
225
  indexOf: function(record, startAt) {
226
- if (!SC.kindOf(record, SC.Record)) return NO ; // only takes records
226
+ if (!SC.kindOf(record, SC.Record)) {
227
+ SC.Logger.warn("Using indexOf on %@ with an object that is not an SC.Record".fmt(record));
228
+ return -1; // only takes records
229
+ }
227
230
 
228
231
  this.flush();
229
232
 
@@ -241,7 +244,10 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
241
244
  @returns {Number} index
242
245
  */
243
246
  lastIndexOf: function(record, startAt) {
244
- if (!SC.kindOf(record, SC.Record)) return NO ; // only takes records
247
+ if (!SC.kindOf(record, SC.Record)) {
248
+ SC.Logger.warn("Using lastIndexOf on %@ with an object that is not an SC.Record".fmt(record));
249
+ return -1; // only takes records
250
+ }
245
251
 
246
252
  this.flush();
247
253
 
@@ -222,9 +222,9 @@ test("Child Status Changed", function() {
222
222
  equals(cr.get('status'), testParent.get('status'), 'after initializing the parent to READY_NEW, check that the child record matches');
223
223
 
224
224
  SC.RunLoop.begin();
225
- store.writeStatus(testParent.storeKey, SC.Record.DIRTY_NEW);
225
+ store.writeStatus(testParent.storeKey, SC.Record.READY_DIRTY);
226
226
  store.dataHashDidChange(testParent.storeKey);
227
- equals(cr.get('status'), testParent.get('status'), 'after setting the parent to DIRTY_NEW, check that the child record matches');
227
+ equals(cr.get('status'), testParent.get('status'), 'after setting the parent to READY_DIRTY, check that the child record matches');
228
228
  SC.RunLoop.end();
229
229
 
230
230
  SC.RunLoop.begin();
@@ -233,3 +233,43 @@ test("Child Status Changed", function() {
233
233
  equals(cr.get('status'), testParent.get('status'), 'after setting the parent to BUSY_REFRESH, check that the child record matches');
234
234
  SC.RunLoop.end();
235
235
  });
236
+
237
+ test("Child Status Matches Store Status", function() {
238
+ var cr;
239
+ var storeStatus;
240
+ cr = testParent.get('info');
241
+
242
+ storeStatus = store.readStatus(cr.storeKey);
243
+ equals(storeStatus, cr.get('status'), 'after initializing the parent to READY_NEW, check that the store status matches for the child');
244
+ equals(cr.get('status'), testParent.get('status'), 'after initializing the parent to READY_NEW, check that the child record matches');
245
+
246
+ SC.RunLoop.begin();
247
+ store.writeStatus(testParent.storeKey, SC.Record.READY_CLEAN);
248
+ store.dataHashDidChange(testParent.storeKey);
249
+ SC.RunLoop.end();
250
+
251
+ storeStatus = store.readStatus(cr.storeKey);
252
+ equals(testParent.get('status'), SC.Record.READY_CLEAN, 'parent status should be READY_CLEAN');
253
+ equals(storeStatus, cr.get('status'), 'after setting the parent to READY_CLEAN, the child\'s status and store status should be READY_CLEAN before calling get(\'status\') on the child');
254
+ equals(cr.get('status'), testParent.get('status'), 'after setting the parent to READY_CLEAN, check that the child record matches');
255
+
256
+ SC.RunLoop.begin();
257
+ store.writeStatus(testParent.storeKey, SC.Record.READY_DIRTY);
258
+ store.dataHashDidChange(testParent.storeKey);
259
+ SC.RunLoop.end();
260
+
261
+ storeStatus = store.readStatus(cr.storeKey);
262
+ equals(testParent.get('status'), SC.Record.READY_DIRTY, 'parent status should be READY_DIRTY');
263
+ equals(storeStatus, cr.get('status'), 'after setting the parent to READY_DIRTY, the child\'s status and store status should be READY_DIRTY before calling get(\'status\') on the child');
264
+ equals(cr.get('status'), testParent.get('status'), 'after setting the parent to READY_DIRTY, check that the child record matches');
265
+
266
+ SC.RunLoop.begin();
267
+ store.writeStatus(testParent.storeKey, SC.Record.BUSY_REFRESH);
268
+ store.dataHashDidChange(testParent.storeKey);
269
+ storeStatus = store.readStatus(cr.storeKey);
270
+ SC.RunLoop.end();
271
+
272
+ equals(testParent.get('status'), SC.Record.BUSY_REFRESH, 'parent status should be BUSY_REFRESH');
273
+ equals(storeStatus, cr.get('status'), 'after setting the parent to BUSY_REFRESH, the child\'s status and store status should be BUSY_REFRESH before calling get(\'status\') on the child');
274
+ equals(cr.get('status'), testParent.get('status'), 'after setting the parent to BUSY_REFRESH, check that the child record matches');
275
+ });
@@ -21,7 +21,7 @@ SC.addInvokeOnceLastDebuggingInfo = function() {
21
21
 
22
22
  SC.ObserverSet.add = function(target, method, context, originatingTarget, originatingMethod, originatingStack) {
23
23
  var targetGuid = (target) ? SC.guidFor(target) : "__this__";
24
-
24
+
25
25
  // get the set of methods
26
26
  var methods = this[targetGuid] ;
27
27
  if (!methods) {
@@ -31,16 +31,16 @@ SC.addInvokeOnceLastDebuggingInfo = function() {
31
31
  this.targets++ ;
32
32
  }
33
33
  methods.add(method) ;
34
-
34
+
35
35
  // context is really useful sometimes but not used that often so this
36
36
  // implementation is intentionally lazy.
37
37
  if (context !== undefined) {
38
- var contexts = methods.contexts ;
39
- if (!contexts) contexts = {};
40
- contexts[SC.guidFor(method)] = context ;
38
+ if (!methods.contexts) methods.contexts = {} ;
39
+ methods.contexts[SC.guidFor(method)] = context ;
41
40
  }
42
-
43
-
41
+
42
+ this._membersCacheIsValid = NO ;
43
+
44
44
  // THIS IS THE PORTION THAT DIFFERS FROM THE STANDARD IMPLEMENTATION
45
45
 
46
46
  // Recording the calling object/function can be a useful debugging tool.
@@ -76,11 +76,6 @@ SC.addInvokeOnceLastDebuggingInfo = function() {
76
76
  originatingStacks[key] = originatingStack;
77
77
  }
78
78
  }
79
-
80
- // THIS IS THE PORTION THAT DIFFERS FROM THE STANDARD IMPLEMENTATION
81
-
82
-
83
- this._membersCacheIsValid = NO ;
84
79
  };
85
80
 
86
81
 
@@ -10,7 +10,8 @@
10
10
  htmlbody('<style> .sc-static-layout { border: 1px red dotted; } </style>');
11
11
 
12
12
  var itemList = [{ title: "Red", value: "red", enabled: YES }, { title: "Green", value: "green" }, { title: "Blue", value: "blue" }],
13
- itemList2 = [{ title: "Cyan", value: "cyan", enabled: YES }, { title: "Magenta", value: "magenta" }, { title: "Yellow", value: "yellow" },{ title: "blacK", value: "black"}];
13
+ itemList2 = [{ title: "Cyan", value: "cyan", enabled: YES }, { title: "Magenta", value: "magenta" }, { title: "Yellow", value: "yellow" },{ title: "blacK", value: "black"}],
14
+ itemList3 = [{ title: "Red", value: "red", enabled: YES, width: 30 }, { title: "Green", value: "green", width: 50 }, { title: "Blue", value: "blue", width: 40 }];
14
15
 
15
16
  var pane = SC.ControlTestPane.design()
16
17
  .add("basic", SC.RadioView, {
@@ -56,6 +57,16 @@ var pane = SC.ControlTestPane.design()
56
57
  items: 'Yes No'.w(),
57
58
  // LAYOUT_VERTICAL is default
58
59
  layoutDirection: SC.LAYOUT_HORIZONTAL
60
+ })
61
+
62
+ .add("horizontal widths", SC.RadioView, {
63
+ value: "",
64
+ isEnabled: YES,
65
+ items: itemList3,
66
+ layoutDirection: SC.LAYOUT_HORIZONTAL,
67
+ itemTitleKey: 'title',
68
+ itemValueKey: 'value',
69
+ itemWidthKey: 'width'
59
70
  });
60
71
 
61
72
  pane.show(); // add a test to show the test pane
@@ -230,3 +241,13 @@ test("enabled first", function() {
230
241
  });
231
242
  });
232
243
 
244
+ test("item widths", function() {
245
+ var radioButtons = pane.view('horizontal widths').$('.sc-radio-button'),
246
+ widths = [30, 50, 40],
247
+ idx = 0, radio;
248
+
249
+ radioButtons.forEach(function(elem) {
250
+ equals(SC.$(elem).width(), widths[idx], 'radio button %@ should width specified by itemWidthKey'.fmt(idx, widths[idx]));
251
+ idx++;
252
+ });
253
+ });
@@ -905,7 +905,7 @@ SC.CollectionView = SC.View.extend(
905
905
  // to reuse it.
906
906
  // (Charles Jolley personally guarantees this code)
907
907
  layer = existing.get('layer');
908
- layer.parentNode.removeChild(layer);
908
+ if (layer && layer.parentNode) layer.parentNode.removeChild(layer);
909
909
 
910
910
  containerView.removeChild(existing);
911
911
  }
@@ -217,7 +217,7 @@ SC.ListView = SC.CollectionView.extend(
217
217
  // prefill the cache with custom rows.
218
218
  cache = this._sclv_offsetCache;
219
219
  if (!cache) {
220
- cache = this._sclv_offsetCache = [];
220
+ cache = [];
221
221
  delta = max = 0 ;
222
222
  custom.forEach(function(idx) {
223
223
  delta += this.rowHeightForContentIndex(idx)-rowHeight;
@@ -225,6 +225,8 @@ SC.ListView = SC.CollectionView.extend(
225
225
  max = idx ;
226
226
  }, this);
227
227
  this._sclv_max = max+1;
228
+ // moved down so that the cache is not marked as initialized until it actually is
229
+ this._sclv_offsetCache = cache;
228
230
  }
229
231
 
230
232
  // now just get the delta for the last custom row before the current
@@ -259,11 +261,13 @@ SC.ListView = SC.CollectionView.extend(
259
261
  if (del.customRowHeightIndexes && (indexes=del.get('customRowHeightIndexes'))) {
260
262
  cache = this._sclv_heightCache ;
261
263
  if (!cache) {
262
- cache = this._sclv_heightCache = [];
264
+ cache = [];
263
265
  content = this.get('content');
264
266
  indexes.forEach(function(idx) {
265
267
  cache[idx] = del.contentIndexRowHeight(this, content, idx);
266
268
  }, this);
269
+ // moved down so that the cache is not marked as initialized until it actually is
270
+ this._sclv_heightCache = cache;
267
271
  }
268
272
 
269
273
  ret = cache[idx];
@@ -500,7 +500,7 @@ SC.ListItemView = SC.View.extend(
500
500
  */
501
501
  _isInsideRightIcon: function(evt) {
502
502
  var del = this.displayDelegate ;
503
- var rightIconKey = this.getDelegateProperty('hasContentRightIcon', del) ;
503
+ var rightIconKey = this.getDelegateProperty('hasContentRightIcon', del) || !SC.none(this.rightIcon);
504
504
  return rightIconKey && this._isInsideElementWithClassName('right-icon', evt);
505
505
  },
506
506
 
@@ -89,6 +89,17 @@ SC.RadioView = SC.View.extend(SC.Control,
89
89
  the title with this itemTitleKey property.
90
90
  */
91
91
  itemTitleKey: null,
92
+
93
+ /**
94
+ If items property is a hash, specify which property will function as
95
+ the item width with this itemWidthKey property. This is only used when
96
+ layoutDirection is set to SC.LAYOUT_HORIONZTAL and can be used to override
97
+ the default value provided by the framework or theme CSS.
98
+
99
+ @property {String}
100
+ @default null
101
+ */
102
+ itemWidthKey: null,
92
103
 
93
104
  /**
94
105
  If items property is a hash, specify which property will function as
@@ -142,9 +153,12 @@ SC.RadioView = SC.View.extend(SC.Control,
142
153
  displayProperties: ['value', '_displayItems'],
143
154
 
144
155
  render: function(context, firstTime) {
145
- var item, idx, icon, name, itemsLength, url, className, disabled, sel, labelText, selectionState, selectionStateClassNames, items = this.get('_displayItems'),
146
- value = this.get('value'),
147
- isArray = SC.isArray(value);
156
+ var items = this.get('_displayItems'),
157
+ value = this.get('value'),
158
+ isArray = SC.isArray(value),
159
+ item, idx, icon, name, width, itemsLength, url,
160
+ className, disabled, sel, labelText,
161
+ selectionState, selectionStateClassNames;
148
162
 
149
163
  context.addClass(this.get('layoutDirection'));
150
164
 
@@ -186,8 +200,11 @@ SC.RadioView = SC.View.extend(SC.Control,
186
200
 
187
201
  labelText = this.escapeHTML ? SC.RenderContext.escapeHTML(item[0]) : item[0];
188
202
 
189
- context.push('<div class="sc-radio-button ',
190
- selectionStateClassNames, '" ',
203
+ width = item[4];
204
+
205
+ context.push('<div class="sc-radio-button ',
206
+ selectionStateClassNames, '" ',
207
+ width ? 'style="width: ' + width + 'px;" ' : '',
191
208
  'aria-checked="', sel ? 'true':'false','" ',
192
209
  'role="radio"' , ' index="', idx,'">',
193
210
  '<span class="button"></span>',
@@ -209,6 +226,10 @@ SC.RadioView = SC.View.extend(SC.Control,
209
226
  } else {
210
227
  sel = NO;
211
228
  }
229
+
230
+ width = item[4];
231
+ if (width) button.width(width);
232
+
212
233
  selectionState = this._getSelectionStateClassNames(item, sel, value, isArray, true);
213
234
  button.attr('aria-checked', sel ? 'true': 'false');
214
235
  // set class of label
@@ -232,11 +253,14 @@ SC.RadioView = SC.View.extend(SC.Control,
232
253
  _displayItems: function() {
233
254
  var items = this.get('items'),
234
255
  loc = this.get('localize'),
235
- titleKey = this.get('itemTitleKey'), valueKey = this.get('itemValueKey'),
256
+ titleKey = this.get('itemTitleKey'),
257
+ valueKey = this.get('itemValueKey'),
258
+ widthKey = this.get('itemWidthKey'),
259
+ isHorizontal = this.get('layoutDirection') === SC.LAYOUT_HORIZONTAL,
236
260
  isEnabledKey = this.get('itemIsEnabledKey'),
237
261
  iconKey = this.get('itemIconKey'),
238
262
  ret = [], max = (items)? items.get('length') : 0,
239
- item, title, value, idx, isArray, isEnabled, icon;
263
+ item, title, width, value, idx, isArray, isEnabled, icon;
240
264
 
241
265
  for(idx=0;idx<max;idx++) {
242
266
  item = items.objectAt(idx);
@@ -253,7 +277,11 @@ SC.RadioView = SC.View.extend(SC.Control,
253
277
  if (titleKey) {
254
278
  title = item.get ? item.get(titleKey) : item[titleKey];
255
279
  } else title = (item.toString) ? item.toString() : null;
256
-
280
+
281
+ if (widthKey && isHorizontal) {
282
+ width = item.get ? item.get(widthKey) : item[widthKey];
283
+ }
284
+
257
285
  if (valueKey) {
258
286
  value = item.get ? item.get(valueKey) : item[valueKey];
259
287
  } else value = item;
@@ -274,11 +302,11 @@ SC.RadioView = SC.View.extend(SC.Control,
274
302
 
275
303
  // localize title if needed
276
304
  if (loc) title = title.loc();
277
- ret.push([title, value, isEnabled, icon]);
305
+ ret.push([title, value, isEnabled, icon, width]);
278
306
  }
279
307
 
280
308
  return ret; // done!
281
- }.property('items', 'itemTitleKey', 'itemValueKey', 'itemIsEnabledKey', 'localize', 'itemIconKey').cacheable(),
309
+ }.property('items', 'itemTitleKey', 'itemWidthKey', 'itemValueKey', 'itemIsEnabledKey', 'localize', 'itemIconKey').cacheable(),
282
310
 
283
311
  /** @private -
284
312
  Will figure out what class names to assign each radio button.
@@ -198,7 +198,7 @@ SC.ScrollerView = SC.View.extend(
198
198
  @private
199
199
  */
200
200
  render: function(context, firstTime) {
201
- var classNames = [],
201
+ var classNames = {},
202
202
  buttons = '',
203
203
  thumbPosition, thumbLength, thumbCenterLength, thumbElement,
204
204
  value, max, scrollerLength, length, pct;
@@ -207,21 +207,21 @@ SC.ScrollerView = SC.View.extend(
207
207
  // style them differently using CSS.
208
208
  switch (this.get('layoutDirection')) {
209
209
  case SC.LAYOUT_VERTICAL:
210
- classNames.push('sc-vertical');
210
+ classNames['sc-vertical'] = YES;
211
211
  break;
212
212
  case SC.LAYOUT_HORIZONTAL:
213
- classNames.push('sc-horizontal');
213
+ classNames['sc-horizontal'] = YES;
214
214
  break;
215
215
  }
216
216
 
217
217
  // The appearance of the scroller changes if disabled
218
- if (!this.get('isEnabled')) classNames.push('disabled');
218
+ classNames['disabled'] = !this.get('isEnabled');
219
219
  // Whether to hide the thumb and buttons
220
- if (this.get('controlsHidden')) classNames.push('controls-hidden');
220
+ classNames['controls-hidden'] = this.get('controlsHidden');
221
221
 
222
222
  // Change the class names of the DOM element all at once to improve
223
223
  // performance
224
- context.addClass(classNames);
224
+ context.setClass(classNames);
225
225
 
226
226
  // Calculate the position and size of the thumb
227
227
  thumbLength = this.get('thumbLength');
@@ -240,7 +240,7 @@ SC.ScrollerView = SC.View.extend(
240
240
  context.push('<div class="track"></div>',
241
241
  '<div class="cap"></div>',
242
242
  buttons,
243
- '<div class="thumb" style="height: '+thumbLength+'px;">',
243
+ '<div class="thumb" style="height: '+thumbLength+'px; top: ' + thumbPosition + 'px;">',
244
244
  '<div class="thumb-center"></div>',
245
245
  '<div class="thumb-top"></div>',
246
246
  '<div class="thumb-bottom"></div></div>');
@@ -249,7 +249,7 @@ SC.ScrollerView = SC.View.extend(
249
249
  context.push('<div class="track"></div>',
250
250
  '<div class="cap"></div>',
251
251
  buttons,
252
- '<div class="thumb" style="width: '+thumbLength+'px;">',
252
+ '<div class="thumb" style="width: '+thumbLength+'px; left: ' + thumbPosition + 'px;">',
253
253
  '<div class="thumb-center"></div>',
254
254
  '<div class="thumb-top"></div>',
255
255
  '<div class="thumb-bottom"></div></div>');
@@ -2,7 +2,7 @@
2
2
  // Project: SproutCore - JavaScript Application Framework
3
3
  // Copyright: ©2006-2010 Sprout Systems, Inc. and contributors.
4
4
  // Portions ©2008-2010 Apple Inc. All rights reserved.
5
- // License: Licened under MIT license (see license.js)
5
+ // License: Licensed under MIT license (see license.js)
6
6
  // ==========================================================================
7
7
 
8
8
  /**
@@ -122,7 +122,9 @@ SC.SelectFieldView = SC.FieldView.extend(
122
122
  var objects = this.get('objects') ;
123
123
  var fieldValue = this.get('value') ;
124
124
  var el, selectElement;
125
-
125
+
126
+ if ( !this.get('isEnabled') ) context.attr('disabled','disabled');
127
+
126
128
  // get the localization flag.
127
129
  var shouldLocalize = this.get('localize');
128
130
 
@@ -208,12 +210,17 @@ SC.SelectFieldView = SC.FieldView.extend(
208
210
  }
209
211
  },
210
212
 
211
- displayProperties: ['objects','nameKey','valueKey'],
213
+ displayProperties: ['objects','nameKey','valueKey','isEnabled'],
212
214
 
213
215
  _objectsObserver: function() {
214
216
  this.set('cpDidChange', YES);
215
217
  }.observes('objects'),
216
-
218
+
219
+ _objectArrayObserver: function() {
220
+ this.set('cpDidChange', YES);
221
+ this.propertyDidChange('objects');
222
+ }.observes('*objects.[]'),
223
+
217
224
  _nameKeyObserver: function() {
218
225
  this.set('cpDidChange', YES);
219
226
  }.observes('nameKey'),
@@ -247,7 +254,8 @@ SC.SelectFieldView = SC.FieldView.extend(
247
254
  var value = sc_super(); // get raw value...
248
255
  var valueKey = this.get('valueKey') ;
249
256
  var objects = this.get('objects') ;
250
- var found, object;
257
+ var found = null; // matching object goes here.
258
+ var object;
251
259
 
252
260
  // Handle empty selection.
253
261
  if (value == '***') {
@@ -260,7 +268,6 @@ SC.SelectFieldView = SC.FieldView.extend(
260
268
 
261
269
  var loc = (SC.typeOf(objects.length) === SC.T_FUNCTION) ? objects.length() : objects.length;
262
270
 
263
- found = null ; // matching object goes here.
264
271
  while(!found && (--loc >= 0)) {
265
272
  object = objects.objectAt? objects.objectAt(loc) : objects[loc] ;
266
273
  if (!object) continue; // null means placeholder; just skip