sproutcore 0.9.17 → 0.9.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/History.txt +45 -2
  2. data/Manifest.txt +10 -0
  3. data/Rakefile +1 -1
  4. data/app_generators/sproutcore/templates/sc-config +8 -2
  5. data/bin/sc-server +4 -0
  6. data/clients/sc_docs/english.lproj/body.css +0 -20
  7. data/clients/sc_docs/english.lproj/body.rhtml +1 -3
  8. data/clients/sc_docs/english.lproj/strings.js +1 -1
  9. data/clients/sc_docs/french.lproj/strings.js +14 -0
  10. data/clients/sc_test_runner/english.lproj/body.css +0 -20
  11. data/clients/sc_test_runner/english.lproj/body.rhtml +1 -3
  12. data/config/hoe.rb +1 -1
  13. data/frameworks/sproutcore/HISTORY +56 -1
  14. data/frameworks/sproutcore/debug/trace.js +81 -0
  15. data/frameworks/sproutcore/debug/unittest.js +2 -1
  16. data/frameworks/sproutcore/english.lproj/buttons.css +5 -2
  17. data/frameworks/sproutcore/english.lproj/core.css +0 -16
  18. data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
  19. data/frameworks/sproutcore/english.lproj/splitview.css +83 -0
  20. data/frameworks/sproutcore/english.lproj/theme.css +21 -5
  21. data/frameworks/sproutcore/foundation/object.js +23 -0
  22. data/frameworks/sproutcore/foundation/string.js +4 -3
  23. data/frameworks/sproutcore/lib/core_views.rb +43 -8
  24. data/frameworks/sproutcore/lib/form_views.rb +2 -2
  25. data/frameworks/sproutcore/lib/index.rhtml +1 -1
  26. data/frameworks/sproutcore/mixins/enumerable.js +4 -8
  27. data/frameworks/sproutcore/mixins/selection_support.js +1 -1
  28. data/frameworks/sproutcore/models/collection.js +14 -3
  29. data/frameworks/sproutcore/models/record.js +6 -5
  30. data/frameworks/sproutcore/models/store.js +3 -3
  31. data/frameworks/sproutcore/panes/picker.js +1 -0
  32. data/frameworks/sproutcore/server/rails_server.js +4 -7
  33. data/frameworks/sproutcore/server/server.js +58 -1
  34. data/frameworks/sproutcore/tests/controllers/object.rhtml +1 -1
  35. data/frameworks/sproutcore/tests/models/collection.rhtml +160 -0
  36. data/frameworks/sproutcore/tests/models/model.rhtml +15 -3
  37. data/frameworks/sproutcore/tests/views/collection/base.rhtml +120 -47
  38. data/frameworks/sproutcore/tests/views/collection/source_list_rendering.rhtml +232 -0
  39. data/frameworks/sproutcore/tests/views/view/frame.rhtml +2 -2
  40. data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +87 -85
  41. data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +25 -26
  42. data/frameworks/sproutcore/views/collection/collection.js +5 -1
  43. data/frameworks/sproutcore/views/field/select_field.js +1 -1
  44. data/frameworks/sproutcore/views/radio_group.js +2 -2
  45. data/frameworks/sproutcore/views/split.js +191 -174
  46. data/frameworks/sproutcore/views/split_divider.js +71 -68
  47. data/frameworks/sproutcore/views/view.js +65 -25
  48. data/lib/sproutcore.rb +4 -1
  49. data/lib/sproutcore/build_tools/html_builder.rb +50 -46
  50. data/lib/sproutcore/build_tools/resource_builder.rb +17 -5
  51. data/lib/sproutcore/bundle_installer.rb +3 -1
  52. data/lib/sproutcore/bundle_manifest.rb +4 -3
  53. data/lib/sproutcore/cssmin.rb +195 -0
  54. data/lib/sproutcore/generator_helper.rb +15 -0
  55. data/lib/sproutcore/helpers/capture_helper.rb +2 -22
  56. data/lib/sproutcore/helpers/dom_id_helper.rb +14 -0
  57. data/lib/sproutcore/helpers/static_helper.rb +6 -2
  58. data/lib/sproutcore/helpers/text_helper.rb +1 -1
  59. data/lib/sproutcore/merb.rb +2 -2
  60. data/lib/sproutcore/renderers/erubis.rb +43 -0
  61. data/lib/sproutcore/renderers/haml.rb +28 -0
  62. data/lib/sproutcore/renderers/sass.rb +42 -0
  63. data/lib/sproutcore/version.rb +1 -1
  64. data/lib/sproutcore/view_helpers.rb +40 -46
  65. data/sc_generators/controller/controller_generator.rb +1 -1
  66. data/sc_generators/language/USAGE +5 -7
  67. data/sc_generators/language/language_generator.rb +1 -1
  68. data/sc_generators/language/templates/strings.js +5 -1
  69. data/sc_generators/model/model_generator.rb +1 -1
  70. data/sc_generators/test/test_generator.rb +1 -1
  71. data/sc_generators/view/view_generator.rb +1 -1
  72. metadata +12 -5
@@ -502,6 +502,9 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate,
502
502
  itemViewForEvent: function(evt)
503
503
  {
504
504
  var view = SC.window.firstViewForEvent( evt );
505
+
506
+ if (!view) return null; // workaround for error on IE8, see Ticket #169
507
+
505
508
  // work up the view hierarchy to find a match...
506
509
  do {
507
510
  // item clicked was the ContainerView itself... i.e. the user clicked outside the child items
@@ -682,7 +685,7 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate,
682
685
  range.length = Math.min(SC.maxRange(range), content.get('length')) - range.start ;
683
686
 
684
687
  var nowShowingRange = this.get('nowShowingRange') ;
685
- fullUpdate = fullUpdate || (SC.intersectRanges(range, nowShowingRange).length <= 0) ;
688
+ fullUpdate = fullUpdate || (this.get('isDirty') && this._needsFullUpdate) || (SC.intersectRanges(range, nowShowingRange).length <= 0) ;
686
689
  this.set('nowShowingRange', range) ;
687
690
 
688
691
  // STEP 3: Update item views.
@@ -977,6 +980,7 @@ SC.CollectionView = SC.View.extend(SC.CollectionViewDelegate,
977
980
 
978
981
  // if grouping is enabled, get the group value and layout based on that.
979
982
  if (groupBy && ((curGroupValue = (cur) ? cur.get(groupBy) : null) !== groupValue)) {
983
+ groupValue = curGroupValue ;
980
984
  var groupView = this.groupViewForGroupValue(groupValue) ;
981
985
  if (groupView) {
982
986
  this.layoutGroupView(groupView, groupValue, idx, false) ;
@@ -135,7 +135,7 @@ SC.SelectFieldView = SC.FieldView.extend(
135
135
  }
136
136
  }
137
137
 
138
- return value ;
138
+ return valueKey ? value : found ;
139
139
  },
140
140
 
141
141
  // when setting the raw value, convert from object...
@@ -40,8 +40,8 @@ SC.RadioGroupView = SC.View.extend({
40
40
  _isEnabledObserver: function() {
41
41
  var newFlag = this.get('isEnabled') ;
42
42
  if (!this.didChangeFor('_isEnabled','isEnabled')) return ;
43
- if (this.radioButtons) {
44
- this.radioButtons.invoke('set','isEnabled',newFlag) ;
43
+ if (this._radioButtons) {
44
+ this._radioButtons.invoke('set','isEnabled',newFlag) ;
45
45
  }
46
46
  }.observes('isEnabled')
47
47
 
@@ -9,49 +9,89 @@ require('mixins/delegate_support');
9
9
  SC.HORIZONTAL = 'horizontal' ;
10
10
  SC.VERTICAL = 'vertical' ;
11
11
 
12
- /**
12
+ /**
13
13
  @class
14
14
 
15
15
  A split view is used to show views that the user can resize or collapse.
16
- To use the split view, you need to add the child views you want layed out
17
- separated by divider views (instances of SC.SplitDividerView).
18
-
19
- When the user clicks and drags on a divider view, it will automatically
20
- resize the views immediately before and after the view. You can constrain
21
- the resizing allowed by the split view either by setting a minThickness and
22
- maxThickness property on the views themselves or by implementing methods
23
- on a delegate object.
16
+ To use the split view, you need to add a top left view followed by an
17
+ instance of SC.SplitDividerView followed by a bottom right view.
18
+
19
+ For example:
20
+
21
+ {{{
22
+ <% view :workspace_container, :class => 'workspace_container' do %>
23
+ <% split_view :workspace, :class => 'sc-app-workspace', :direction => :vertical do %>
24
+ <% view :top_view, :can_collapse => false, :min_thickness => 50 do %>
25
+ <p>My top view</p>
26
+ <% end %>
27
+ <%= split_divider_view %>
28
+ <% view :bottom_view, :collapse_at_thickness => 100 do %>
29
+ <p>My bottom view</p>
30
+ <% end %>
31
+ <% end%>
32
+ <% end %>
33
+ }}}
34
+
35
+ When the user clicks and drags on a split divider view, it will
36
+ automatically resize the views immediately before and after the split
37
+ divider view. You can constrain the resizing allowed by the split view
38
+ either by setting a minThickness and maxThickness property on the views
39
+ themselves or by implementing the method splitViewConstrainThickness on
40
+ a delegate object.
24
41
 
25
42
  In addition to resizing views, users can also collapse views by double
26
- clicking on a divider view. When a view is collapsed, it's isVisible
43
+ clicking on a split divider view. When a view is collapsed, it's isVisible
27
44
  property is set to NO and its space it removed from the view. Double
28
- clicking on a divider again will restore a collapse view. A user can also
45
+ clicking on a divider again will restore a collapsed view. A user can also
29
46
  start to drag the divider to show the collapsed view.
30
-
31
- You can programmatically control collapsing behavior by setting the
32
- canCollapseViews property on the SplitView, a canCollapse property on each
33
- child view, or by implementing the appropriate delegate method.
34
-
35
- Finally, SplitViews can layout their child views either horizontally or
47
+
48
+ You can programmatically control collapsing behavior using various properties
49
+ on either the split view or its child views, and/or by implementing the
50
+ method splitViewCanCollapse on a delegate object.
51
+
52
+ Finally, SplitViews can layout their child views either horizontally or
36
53
  vertically. To choose the direction of layout set the layoutDirection
37
- property on the view. This property should be set when the view is created.
38
- Changing it dynamically will have an unknown effect.
54
+ property on the view (or the :direction option with the view helper).
55
+ This property should be set when the view is created. Changing it
56
+ dynamically will have an unknown effect.
57
+
58
+ @property {Boolean} layoutDirection Either SC.HORIZONTAL or SC.VERTICAL.
59
+ Defaults to SC.HORIZONTAL. Use the :direction option with the split_view
60
+ viewhelper.
61
+
62
+ @property {Boolean} canCollapseViews Set to NO when you don't want any of
63
+ the child views to collapse. Defaults to YES. Use the :can_collapse_views
64
+ option with the split_view viewhelper.
65
+
66
+ In addition, the top/left and bottom/right child views can have these
67
+ properties:
39
68
 
69
+ @property {Number} minThickness The minimum thickness of the child view
70
+ @property {Number} maxThickness The maximum thickness of the child view
71
+ @property {Number} collapseAtThickness When the divider is dragged beyond
72
+ the point where the thickness of this view would become less than the value
73
+ of this property, then collapse the view.
74
+ @property {Boolean} canCollapse Set to NO when you don't want the child view
75
+ to collapse. Defaults to YES.
76
+ @property {Boolean} isCollapsed YES if the child view is collapsed, NO
77
+ otherwise.
78
+
40
79
  @extends SC.View
41
80
  @extends SC.DelegateSupport
42
-
81
+
43
82
  @author Charles Jolley
83
+ @author Lawrence Pit
44
84
  */
45
85
  SC.SplitView = SC.View.extend(SC.DelegateSupport,
46
86
  /** @scope SC.SplitView.prototype */ {
47
87
 
48
88
  emptyElement: '<div class="sc-split-view"></div>',
49
-
89
+
50
90
  /**
51
91
  delegate for controlling split view behavior.
52
92
  */
53
93
  delegate: null,
54
-
94
+
55
95
  /**
56
96
  Direction of layout. Must be SC.HORIZONTAL || SC.VERTICAL.
57
97
  */
@@ -66,214 +106,191 @@ SC.SplitView = SC.View.extend(SC.DelegateSupport,
66
106
  Used by split divider to decide if the view can be collapsed.
67
107
  */
68
108
  canCollapseView: function(view) {
69
- if (!this.get('canCollapseViews')) return NO ;
70
- if (view.get('canCollapse') === NO) return NO ;
71
109
  return this.invokeDelegateMethod(this.delegate, 'splitViewCanCollapse', this, view) ;
72
110
  },
73
-
111
+
74
112
  /**
75
- One view in your array must have a flexible width to allow proper
76
- resizing. You can set this view manually with this outlet or you can
77
- just let the split view choose the center-most view.
78
-
79
- Views to the left/top of this view will be anchored to the left/top of
80
- the parent view. Views to the right/bottom of this view will be anchored
81
- to the right/bottom.
113
+ Returns the thickness for a given view.
114
+
115
+ @param {SC.View} view the view to get.
116
+ @returns the view with the width.
82
117
  */
83
- flexibleView: null,
84
-
118
+ getThicknessForView: function(view) {
119
+ var direction = this.get('layoutDirection') ;
120
+ var ret = view.get('frame') ;
121
+ return (direction === SC.HORIZONTAL) ? ret.width : ret.height ;
122
+ },
123
+
85
124
  /**
86
125
  Sets the thickness of the named view and then lays out the rest of the
87
126
  views.
88
-
127
+
89
128
  @param {SC.View} view the view to adjust. Must not be a divider.
90
- @param {Number} offset the new desired offset
91
- @returns the actual allowed offset
129
+ @param {Number} proposedThickness the new desired thickness
130
+ @returns the actual thickness
92
131
  */
93
- setThicknessForView: function(view, thickness) {
132
+ setThicknessForView: function(view, proposedThickness) {
94
133
  if (view.get('parentNode') != this) {
95
- throw "view must belong to reciever (view: %@)".fmt(view);
134
+ throw "view must belong to receiver (view: %@)".fmt(view);
135
+ }
136
+
137
+ var views = this.get('childNodes') ;
138
+ var tl_view = views[0] ; // top/left view
139
+ var br_view = views[2] ; // bottom/right view
140
+ var tl_view_thickness = this.getThicknessForView(tl_view);
141
+ var br_view_thickness = this.getThicknessForView(br_view);
142
+
143
+ var minAvailable = this.getThicknessForView(views[1]) ; // thickness of divider
144
+ var maxAvailable = 0;
145
+ if (!tl_view.get("isCollapsed")) maxAvailable += this.getThicknessForView(tl_view) ;
146
+ if (!br_view.get("isCollapsed")) maxAvailable += this.getThicknessForView(br_view) ;
147
+
148
+ if (view == br_view) {
149
+ proposedThickness = maxAvailable - proposedThickness ;
150
+ view = tl_view ;
151
+ } else if (view != tl_view) {
152
+ throw "You can only set the thickness for the top/left or bottom/right views"
96
153
  }
97
154
 
155
+ var thickness = proposedThickness;
98
156
  var direction = this.get('layoutDirection') ;
99
-
100
- // constrain to thickness set on view.
101
- var max = view.get('maxThickness') ;
102
- var min = view.get('minThickness') ;
103
- if (max != null) thickness = Math.min(max, thickness) ;
157
+ var bottomRightCanCollapse = this.canCollapseView(br_view);
158
+
159
+ // constrain to thickness set on top/left
160
+ var max = tl_view.get('maxThickness') ;
161
+ var min = tl_view.get('minThickness') ;
162
+ if (max != null) thickness = Math.min(max, thickness) ;
104
163
  if (min != null) thickness = Math.max(min, thickness) ;
105
-
164
+
165
+ // constrain to thickness set on bottom/right
166
+ max = br_view.get('maxThickness') ;
167
+ min = br_view.get('minThickness') ;
168
+ bottomRightThickness = maxAvailable - thickness ;
169
+ if (max != null) bottomRightThickness = Math.min(max, bottomRightThickness) ;
170
+ if (min != null) bottomRightThickness = Math.max(min, bottomRightThickness) ;
171
+ thickness = maxAvailable - bottomRightThickness ;
172
+
106
173
  // constrain to thickness determined by delegate.
107
- thickness = this.invokeDelegateMethod(this.delegate, 'splitViewConstrainThickness', this, view, thickness) ;
108
-
109
- // thickness cannot be greater than the total of all the other views (
110
- // except for the flexibleView) added together.
111
-
112
- // available = total minus thickness of all views except "view" and
113
- // "flexible view" that is the same as thickness 'view' plus thickness
114
- // 'flexible view'
115
- var flexibleView = this.get('flexibleView');
116
- var available = this.thicknessForView(view) +
117
- this.thicknessForView(flexibleView);
118
-
119
- thickness = Math.min(thickness, available) ;
120
-
121
- // cannot be less than 0
174
+ thickness = this.invokeDelegateMethod(this.delegate, 'splitViewConstrainThickness', this, tl_view, thickness) ;
175
+
176
+ // cannot be more than what's available
177
+ thickness = Math.min(thickness, maxAvailable) ;
178
+
179
+ // cannot be less than zero
122
180
  thickness = Math.max(0, thickness) ;
123
-
181
+
182
+ var tlCollapseAtThickness = tl_view.get('collapseAtThickness') ;
183
+ if (!tlCollapseAtThickness) tlCollapseAtThickness = 0 ;
184
+ var brCollapseAtThickness = br_view.get('collapseAtThickness') ;
185
+ brCollapseAtThickness = (brCollapseAtThickness == null) ? maxAvailable : (maxAvailable - brCollapseAtThickness);
186
+
187
+ if ((proposedThickness <= tlCollapseAtThickness) && this.canCollapseView(tl_view)) {
188
+ // want to collapse top/left, check if this doesn't violate the max thickness of bottom/right
189
+ max = br_view.get('maxThickness');
190
+ if (!max || (minAvailable + maxAvailable) <= max) {
191
+ // collapse top/left view, even if it has a minThickness
192
+ thickness = 0 ;
193
+ }
194
+ } else if (proposedThickness >= brCollapseAtThickness && this.canCollapseView(br_view)) {
195
+ // want to collapse bottom/right, check if this doesn't violate the max thickness of top/left
196
+ max = tl_view.get('maxThickness');
197
+ if (!max || (minAvailable + maxAvailable) <= max) {
198
+ // collapse bottom/right view, even if it has a minThickness
199
+ thickness = maxAvailable;
200
+ }
201
+ }
202
+
124
203
  // now apply constrained value
125
- if (thickness != this.thicknessForView(view)) {
126
-
204
+ if (thickness != this.getThicknessForView(tl_view)) {
205
+
127
206
  // un-collapse if needed.
128
- view.set('isCollapsed', (thickness <= 0)) ;
129
-
207
+ tl_view.set('isCollapsed', thickness == 0) ;
208
+ br_view.set('isCollapsed', thickness >= maxAvailable) ;
209
+
130
210
  // set new frame
131
211
  var f = (direction === SC.HORIZONTAL) ? { width: thickness } : { height: thickness } ;
132
- view.set('frame', f) ;
133
-
212
+ tl_view.set('frame', f) ;
213
+
134
214
  // and layout
135
215
  this.layout() ;
136
216
  }
137
217
 
218
+ return thickness ;
138
219
  },
139
220
 
140
- /**
141
- Returns the thickness for a given view.
142
-
143
- @param {SC.View} view the view to get.
144
- @returns the view with the width.
145
- */
146
- thicknessForView: function(view) {
147
- var direction = this.get('layoutDirection') ;
148
- var ret = view.get('frame') ;
149
- return (direction === SC.HORIZONTAL) ? ret.width : ret.height ;
150
- },
151
-
152
- /**
153
- Finds the flexible view.
154
-
155
- This will use the flexibleView property if you set it or use the center
156
- most view that is not a divider.
157
- */
158
- computeFlexibleView: function() {
159
- var flexibleView = this.get('flexibleView') ;
160
- var originalFlexibleView = flexibleView ;
161
- if (!flexibleView) {
162
- var views = this.get('childNodes') ;
163
- flexibleView = views[Math.ceil(views.length/2)] ;
164
- }
165
-
166
- // If the flexible view is a divider, find the first non-g.
167
- while(flexibleView && (flexibleView instanceof SC.SplitDividerView)) {
168
- flexibleView = flexibleView.get('nextSibling') ;
169
- }
170
-
171
- // save new flexible view if we had to fix it up.
172
- if (originalFlexibleView !== flexibleView) {
173
- this.set('flexibleView', flexibleView);
174
- }
175
-
176
- return flexibleView;
177
- },
178
-
221
+
222
+
179
223
  /**
180
224
  Layout the views.
181
-
225
+
182
226
  This method needs to be called anytime you change the view thicknesses
183
227
  to make sure they are arranged properly. This will setup the views so
184
228
  that they can resize appropriately.
185
229
  */
186
230
  layout: function() {
187
-
188
231
  var views = this.get('childNodes') ;
189
-
190
- // find the flexible view, if it is not set.
191
- var flexibleView = this.computeFlexibleView();
192
-
193
- // everything before the flexible view is anchored to the left/top
232
+ var topLeftThickness = this.getThicknessForView(views[0]) ;
233
+ var dividerThickness = this.getThicknessForView(views[1]) ;
194
234
  var direction = this.get('layoutDirection') ;
235
+
236
+ // top/left view
195
237
  var view = views[0];
196
- var offset = 0 ;
197
- while(view && (view !== flexibleView)) {
198
- var isCollapsed = view.get('isCollapsed') || NO ;
199
- view.setIfChanged('isVisible', !isCollapsed) ;
200
- if (!isCollapsed) {
201
- view.viewFrameWillChange() ;
202
- if (direction == SC.HORIZONTAL) {
203
- view.setIfChanged('styleLeft', offset) ;
204
- view.setIfChanged('styleRight', null) ;
205
- } else {
206
- view.setIfChanged('styleTop', offset) ;
207
- view.setIfChanged('styleBottom', null) ;
208
- }
209
- view.viewFrameDidChange() ;
210
-
211
- offset += this.thicknessForView(view) ;
212
- }
213
- view = view.get('nextSibling') ;
214
- }
238
+ var isCollapsed = view.get('isCollapsed') || NO ;
239
+ view.setIfChanged('isVisible', !isCollapsed) ;
215
240
 
216
- var flexHead = offset ;
217
-
218
- // everything after the flexible view is anchored to the right/bottom.
219
- var view = views.last() ;
220
- var offset = 0;
221
- while(view && (view !== flexibleView)) {
222
- var isCollapsed = view.get('isCollapsed') || NO ;
223
- view.setIfChanged('isVisible', !isCollapsed) ;
224
- if (!isCollapsed) {
225
- view.viewFrameWillChange() ;
226
- if (direction == SC.HORIZONTAL) {
227
- view.setIfChanged('styleLeft', null) ;
228
- view.setIfChanged('styleRight', offset) ;
229
- } else {
230
- view.setIfChanged('styleTop', null) ;
231
- view.setIfChanged('styleBottom', offset) ;
232
- }
233
- view.viewFrameDidChange() ;
234
-
235
- offset += this.thicknessForView(view) ;
236
- }
237
- view = view.get('previousSibling') ;
241
+ // split divider view
242
+ view = views[1] ;
243
+ view.viewFrameWillChange() ;
244
+ if (direction == SC.HORIZONTAL) {
245
+ view.setIfChanged('styleLeft', topLeftThickness) ;
246
+ } else {
247
+ view.setIfChanged('styleTop', topLeftThickness) ;
238
248
  }
239
-
240
- var flexTail = offset ;
241
-
242
- if (flexibleView) {
243
- view = flexibleView ;
249
+ view.viewFrameDidChange() ;
250
+
251
+ // bottom/right view
252
+ view = views[2] ;
253
+ var isCollapsed = view.get('isCollapsed') || NO ;
254
+ view.setIfChanged('isVisible', !isCollapsed) ;
255
+ if (!isCollapsed) {
244
256
  view.viewFrameWillChange() ;
245
257
  if (direction == SC.HORIZONTAL) {
246
- view.setIfChanged('styleLeft', flexHead) ;
247
- view.setIfChanged('styleRight', flexTail) ;
258
+ view.setIfChanged('styleLeft', topLeftThickness + dividerThickness) ;
259
+ view.setIfChanged('styleRight', 0) ;
248
260
  view.setIfChanged('styleWidth', null) ;
249
261
  } else {
250
- view.setIfChanged('styleTop', flexHead) ;
251
- view.setIfChanged('styleBottom', flexTail) ;
262
+ view.setIfChanged('styleTop', topLeftThickness + dividerThickness) ;
263
+ view.setIfChanged('styleBottom', 0) ;
252
264
  view.setIfChanged('styleHeight', null) ;
253
265
  }
254
266
  view.viewFrameDidChange() ;
255
267
  }
256
-
257
268
  },
258
269
 
259
270
  /**
260
271
  (DELEGATE) Control whether a view can be collapsed.
261
-
262
- The default implemention returns YES.
263
-
272
+
273
+ The default implemention returns NO if the split view property
274
+ canCollapseViews is set to NO or when the given view has
275
+ property canCollapse set to NO, otherwise it returns YES.
276
+
264
277
  @param {SC.SplitView} splitView the split view
265
278
  @param {SC.View} view the view we want to collapse.
266
279
  @returns {Boolean} YES to allow collapse.
267
280
  */
268
- splitViewCanCollapse: function(splitView, view) { return YES; },
281
+ splitViewCanCollapse: function(splitView, view) {
282
+ if (splitView.get('canCollapseViews') === NO) return NO ;
283
+ if (view.get('canCollapse') === NO) return NO ;
284
+ return YES ;
285
+ },
269
286
 
270
287
  /**
271
288
  (DELEGATE) Constrain a views allowed thickness.
272
-
289
+
273
290
  The default implementation allows any thickness. The view will
274
- automatically constrain the view to not allow views to overflow the
291
+ automatically constrain the view to not allow views to overflow the
275
292
  visible area.
276
-
293
+
277
294
  @param {SC.SplitView} splitView the split view
278
295
  @param {SC.View} view the view in question
279
296
  @param {Number} proposedThickness the proposed thickness.
@@ -282,14 +299,14 @@ SC.SplitView = SC.View.extend(SC.DelegateSupport,
282
299
  splitViewConstrainThickness: function(splitView, view, proposedThickness) {
283
300
  return proposedThickness;
284
301
  },
285
-
302
+
286
303
  /** @private */
287
304
  init: function() {
288
305
  sc_super() ;
289
306
  this.addClassName(this.get('layoutDirection')) ;
290
307
  }
291
-
292
-
308
+
309
+
293
310
  }) ;
294
311
 
295
312