sproutcore 1.11.0.rc2 → 1.11.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +8 -8
  2. data/CHANGELOG +10 -0
  3. data/VERSION.yml +1 -1
  4. data/lib/frameworks/sproutcore/CHANGELOG.md +114 -1
  5. data/lib/frameworks/sproutcore/apps/showcase/views/views_item_view.js +1 -7
  6. data/lib/frameworks/sproutcore/apps/showcase/views/views_list_view.js +9 -9
  7. data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +167 -5
  8. data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +24 -8
  9. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/stack_layout.js +737 -0
  10. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/layout.js +0 -6
  11. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +11 -7
  12. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane_statechart.js +7 -11
  13. data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/child_view_layout_protocol.js +8 -3
  14. data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/observable_protocol.js +9 -6
  15. data/lib/frameworks/sproutcore/frameworks/{desktop/protocols/responder.js → core_foundation/protocols/responder_protocol.js} +83 -17
  16. data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/{sparse_array_delegate.js → sparse_array_delegate_protocol.js} +11 -7
  17. data/lib/frameworks/sproutcore/frameworks/core_foundation/protocols/view_transition_protocol.js +11 -6
  18. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/color.js +2 -2
  19. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/page.js +0 -22
  20. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +61 -56
  21. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/main_pane.js +2 -2
  22. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/append_remove.js +3 -3
  23. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/animation.js +63 -39
  24. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/border_frame_test.js +28 -28
  25. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/createLayer.js +10 -4
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layout.js +102 -1
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutDidChange.js +4 -4
  28. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +103 -103
  29. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/replaceAllChildren_test.js +1 -1
  30. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/view.js +77 -1
  31. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/view_states_test.js +18 -17
  32. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +42 -49
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +5 -6
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +16 -5
  35. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +241 -102
  36. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +1 -4
  37. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +0 -11
  38. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/statechart.js +993 -610
  39. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/theming.js +3 -2
  40. data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +6 -11
  41. data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +94 -27
  42. data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +133 -53
  43. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +30 -35
  44. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/writeAttribute.js +3 -2
  45. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/writeDataHash.js +73 -29
  46. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/conflictedStoreKeys_test.js +156 -0
  47. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/dataSourceCallbacks.js +61 -37
  48. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/find.js +2 -2
  49. data/lib/frameworks/sproutcore/frameworks/datetime/frameworks/core/system/datetime.js +68 -39
  50. data/lib/frameworks/sproutcore/frameworks/designer/tests/coders/page.js +1 -2
  51. data/lib/frameworks/sproutcore/frameworks/desktop/panes/panel.js +8 -6
  52. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +80 -14
  53. data/lib/frameworks/sproutcore/frameworks/desktop/panes/sheet.js +2 -2
  54. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/{drag_data_source.js → drag_data_source_protocol.js} +16 -10
  55. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/{drag_source.js → drag_source_protocol.js} +28 -26
  56. data/lib/frameworks/sproutcore/frameworks/desktop/protocols/{drop_target.js → drop_target_protocol.js} +73 -75
  57. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +4 -4
  58. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/panel/ui.js +39 -23
  59. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/mouse.js +120 -97
  60. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/list/rowSizeForContentIndex.js +26 -25
  61. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/ui.js +3 -3
  62. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +5 -0
  63. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/{dividers.js → dividers_test.js} +38 -38
  64. data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +29 -14
  65. data/lib/frameworks/sproutcore/frameworks/desktop/views/menu_scroll.js +2 -1
  66. data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll_view.js +13 -18
  67. data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +41 -35
  68. data/lib/frameworks/sproutcore/frameworks/desktop/views/slider.js +14 -14
  69. data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +41 -26
  70. data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +2 -12
  71. data/lib/frameworks/sproutcore/frameworks/foundation/gestures/tap.js +2 -2
  72. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_resize.js +14 -10
  73. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/gesturable.js +104 -63
  74. data/lib/frameworks/sproutcore/frameworks/foundation/protocols/swap_transition_protocol.js +9 -4
  75. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/auto_mixin_tests.js +1 -2
  76. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/auto_resize_test.js +33 -33
  77. data/lib/frameworks/sproutcore/frameworks/foundation/tests/transitions/view_transitions_test.js +5 -5
  78. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/methods.js +0 -4
  79. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/transition_test.js +0 -4
  80. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +0 -2
  81. data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +12 -8
  82. data/lib/frameworks/sproutcore/frameworks/media/resources/silence.mp3 +0 -0
  83. data/lib/frameworks/sproutcore/frameworks/media/tests/audio.js +69 -0
  84. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +1 -0
  85. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
  86. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +11 -4
  87. data/lib/frameworks/sproutcore/frameworks/runtime/protocols/mixin_protocol.js +150 -0
  88. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +447 -137
  89. data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +9 -15
  90. data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +19 -17
  91. data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +188 -16
  92. data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +1 -1
  93. data/lib/frameworks/sproutcore/frameworks/template_view/panes/template.js +0 -3
  94. data/lib/frameworks/sproutcore/frameworks/template_view/tests/panes/template.js +0 -17
  95. data/lib/frameworks/sproutcore/frameworks/template_view/tests/views/template/collection.js +43 -26
  96. data/lib/frameworks/sproutcore/frameworks/template_view/views/bindable_span.js +9 -2
  97. data/lib/frameworks/sproutcore/themes/ace/resources/collection/normal/list.css +0 -1
  98. data/lib/frameworks/sproutcore/themes/ace/resources/scroll/scroll.css +3 -0
  99. data/sproutcore.gemspec +3 -3
  100. metadata +19 -17
  101. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/horizontal_stack_layout.js +0 -465
  102. data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/vertical_stack_layout.js +0 -472
  103. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/build.js +0 -87
  104. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/build_children.js +0 -89
@@ -12,7 +12,7 @@ var parentView;
12
12
  /*
13
13
  * SC.CoreView.UNRENDERED
14
14
  * SC.CoreView.UNATTACHED
15
- * SC.CoreView.UNATTACHED_BY_PARENT
15
+ * SC.CoreView.ATTACHED_PARTIAL
16
16
  * SC.CoreView.ATTACHED_SHOWING
17
17
  * SC.CoreView.ATTACHED_SHOWN
18
18
  * SC.CoreView.ATTACHED_HIDING
@@ -5,7 +5,7 @@
5
5
  // License: Licensed under MIT license (see license.js)
6
6
  // ==========================================================================
7
7
 
8
- /*global module test equals context ok */
8
+ /*globals module, test, equals, context, ok, same */
9
9
 
10
10
  module("SC.View");
11
11
 
@@ -62,3 +62,79 @@ test("it still works with the backward compatible theme property when extending"
62
62
  equals(1, count, "theme observers should get called");
63
63
  });
64
64
 
65
+ var view;
66
+ module("SC.View methods", {
67
+ setup: function () {
68
+ view = SC.View.create({});
69
+ },
70
+
71
+ teardown: function () {
72
+ view.destroy();
73
+ view = null;
74
+ }
75
+ });
76
+
77
+ test("_callOnChildViews", function () {
78
+ var aContext = 'abc',
79
+ callees = [],
80
+ contexts = [],
81
+ childView = SC.View.create({
82
+ childViews: ['grandChildView'],
83
+ calledFunction: function (context) {
84
+ callees.push(this);
85
+ if (context) { contexts.push(context); }
86
+ },
87
+
88
+ grandChildView: SC.View.extend({
89
+ calledFunction: function (context) {
90
+ callees.push(this);
91
+ if (context) { contexts.push(context); }
92
+ }
93
+ })
94
+ }),
95
+ grandChildView;
96
+
97
+ // Add the child view (and grandchild view).
98
+ view.appendChild(childView);
99
+
100
+ // Grab the grandchild view for easy reference.
101
+ grandChildView = childView.get('childViews').objectAt(0);
102
+
103
+ // Call the function by default (top-down).
104
+ view._callOnChildViews('calledFunction');
105
+ same(callees, [childView, grandChildView], "The child view function should be called top-down.");
106
+
107
+ // Reset.
108
+ callees.length = 0;
109
+ contexts.length = 0;
110
+
111
+ // Call the function top-down.
112
+ view._callOnChildViews('calledFunction', true);
113
+ same(callees, [childView, grandChildView], "The child view function should be called top-down.");
114
+
115
+ // Reset.
116
+ callees.length = 0;
117
+ contexts.length = 0;
118
+
119
+ // Call the function top-down with context.
120
+ view._callOnChildViews('calledFunction', true, aContext);
121
+ same(callees, [childView, grandChildView], "The child view function should be called top-down.");
122
+ same(contexts, [aContext, aContext], "The child view function when called should receive the context.");
123
+
124
+ // Reset.
125
+ callees.length = 0;
126
+ contexts.length = 0;
127
+
128
+ // Call the function bottom-up.
129
+ view._callOnChildViews('calledFunction', false);
130
+ same(callees, [grandChildView, childView], "The child view function should be called bottom-up.");
131
+
132
+ // Reset.
133
+ callees.length = 0;
134
+ contexts.length = 0;
135
+
136
+ // Call the function bottom-up with context.
137
+ view._callOnChildViews('calledFunction', false, aContext);
138
+ same(callees, [grandChildView, childView], "The child view function should be called bottom-up.");
139
+ same(contexts, [aContext, aContext], "The child view function when called should receive the context.");
140
+ });
@@ -300,17 +300,17 @@ test("Test adding a child brings that child to the same state as the parentView.
300
300
  // Render the view.
301
301
  view._doRender();
302
302
  equals(view.viewState, SC.CoreView.UNATTACHED, "A rendered child view of unrendered parentView should be in the state");
303
- equals(child.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "A rendered child view of unrendered parentView's child view should be in the state");
303
+ equals(child.viewState, SC.CoreView.ATTACHED_PARTIAL, "A rendered child view of unrendered parentView's child view should be in the state");
304
304
  ok(view.get('_isRendered'), "_isRendered should be true");
305
305
  ok(!view.get('isAttached'), "isAttached should be false");
306
306
  ok(!view.get('isVisibleInWindow'), "isVisibleInWindow should be false");
307
307
 
308
308
  // Attach the view.
309
309
  view._doAttach(document.body);
310
- equals(view.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "An attached child view of unrendered parentView should be in the state");
311
- equals(child.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "An attached child view of unrendered parentView's child view should be in the state");
310
+ equals(view.viewState, SC.CoreView.ATTACHED_PARTIAL, "An attached child view of unrendered parentView should be in the state");
311
+ equals(child.viewState, SC.CoreView.ATTACHED_PARTIAL, "An attached child view of unrendered parentView's child view should be in the state");
312
312
  ok(view.get('_isRendered'), "_isRendered should be true");
313
- ok(!view.get('isAttached'), "isAttached should be false");
313
+ ok(view.get('isAttached'), "isAttached should be true");
314
314
  ok(!view.get('isVisibleInWindow'), "isVisibleInWindow should be false");
315
315
 
316
316
  // Reset
@@ -321,18 +321,18 @@ test("Test adding a child brings that child to the same state as the parentView.
321
321
  parentView._doRender();
322
322
  view._doAdopt(parentView);
323
323
  equals(parentView.viewState, SC.CoreView.UNATTACHED, "A newly created parentView that is rendered should be in the state");
324
- equals(view.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "A newly created child view of unattached parentView should be in the state");
325
- equals(child.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "A newly created child view of unattached parentView's child view should be in the state");
324
+ equals(view.viewState, SC.CoreView.ATTACHED_PARTIAL, "A newly created child view of unattached parentView should be in the state");
325
+ equals(child.viewState, SC.CoreView.ATTACHED_PARTIAL, "A newly created child view of unattached parentView's child view should be in the state");
326
326
  ok(view.get('_isRendered'), "_isRendered should be true");
327
- ok(!view.get('isAttached'), "isAttached should be false");
327
+ ok(view.get('isAttached'), "isAttached should be true");
328
328
  ok(!view.get('isVisibleInWindow'), "isVisibleInWindow should be false");
329
329
 
330
330
  // Attach the view.
331
331
  view._doAttach(document.body);
332
- equals(view.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "An attached child view of unattached parentView should be in the state");
333
- equals(child.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "An attached child view of unattached parentView's child view should be in the state");
332
+ equals(view.viewState, SC.CoreView.ATTACHED_PARTIAL, "An attached child view of unattached parentView should be in the state");
333
+ equals(child.viewState, SC.CoreView.ATTACHED_PARTIAL, "An attached child view of unattached parentView's child view should be in the state");
334
334
  ok(view.get('_isRendered'), "_isRendered should be true");
335
- ok(!view.get('isAttached'), "isAttached should be false");
335
+ ok(view.get('isAttached'), "isAttached should be true");
336
336
  ok(!view.get('isVisibleInWindow'), "isVisibleInWindow should be false");
337
337
 
338
338
  // Reset
@@ -365,8 +365,8 @@ test("Test showing and hiding parentView updates child views.", function () {
365
365
  parentView._doAttach(document.body);
366
366
  view._doAdopt(parentView);
367
367
  equals(parentView.viewState, SC.CoreView.ATTACHED_SHOWN, "A newly created parentView that is attached should be in the state");
368
- equals(view.viewState, SC.CoreView.ATTACHED_SHOWN, "A newly created child view of unattached parentView should be in the state");
369
- equals(child.viewState, SC.CoreView.ATTACHED_SHOWN, "A newly created child view of unattached parentView's child view should be in the state");
368
+ equals(view.viewState, SC.CoreView.ATTACHED_SHOWN, "A newly created child view of attached parentView should be in the state");
369
+ equals(child.viewState, SC.CoreView.ATTACHED_SHOWN, "A newly created child view of attached parentView's child view should be in the state");
370
370
  ok(view.get('isVisibleInWindow'), "isVisibleInWindow should be true");
371
371
 
372
372
  // Hide the parentView.
@@ -414,8 +414,8 @@ test("Test showing and hiding parentView updates child views.", function () {
414
414
  view._doAdopt(parentView);
415
415
 
416
416
  // Attach a parentView with children
417
- equals(view.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "A child view of unattached parentView should be in the state");
418
- equals(child.viewState, SC.CoreView.UNATTACHED_BY_PARENT, "A child view of unattached parentView's child view should be in the state");
417
+ equals(view.viewState, SC.CoreView.ATTACHED_PARTIAL, "A child view of unattached parentView should be in the state");
418
+ equals(child.viewState, SC.CoreView.ATTACHED_PARTIAL, "A child view of unattached parentView's child view should be in the state");
419
419
  parentView._doAttach(document.body);
420
420
  equals(view.viewState, SC.CoreView.ATTACHED_SHOWN, "A child view of attached_shown parentView should be in the state");
421
421
  equals(child.viewState, SC.CoreView.ATTACHED_SHOWN, "A child view of attached_shown parentView's child view should be in the state");
@@ -434,7 +434,7 @@ test("Test showing parentView with transitionShow", function () {
434
434
  parentView._doRender();
435
435
  parentView._doAttach(document.body);
436
436
 
437
- SC.run(function() { parentView.set('isVisible', YES) });
437
+ SC.run(function() { parentView.set('isVisible', YES); });
438
438
 
439
439
  equals(parentView.viewState, SC.View.ATTACHED_SHOWING, "Upon being made visible, a view with a transition is in state");
440
440
  equals(childView.viewState, SC.View.ATTACHED_SHOWN, "A visible view whose parent is ATTACHED_SHOWING is in state.");
@@ -460,7 +460,7 @@ test("Test hiding with transitionHide", function () {
460
460
  SC.run(function () {
461
461
  parentView._doHide();
462
462
  });
463
- ok(parentView.get('isVisibleInWindow'), "isVisibleInWindow of parentView should be false");
463
+ ok(parentView.get('isVisibleInWindow'), "isVisibleInWindow of parentView should be true");
464
464
  ok(view.get('isVisibleInWindow'), "isVisibleInWindow should be true");
465
465
  ok(child.get('isVisibleInWindow'), "isVisibleInWindow of child should be true");
466
466
 
@@ -482,7 +482,8 @@ test("Adjusting unrelated layout property (not specified in transition's layoutP
482
482
  view.adjust('opacity', 0);
483
483
  view.invokeNext(view.didTransitionIn);
484
484
  }
485
- }
485
+ };
486
+
486
487
  var view = SC.View.create({
487
488
  transitionIn: transition,
488
489
  layout: { height: 40 },
@@ -404,7 +404,9 @@ SC.CoreView.reopen(
404
404
  @returns {SC.View} receiver
405
405
  */
406
406
  createLayer: function () {
407
- this._doRender();
407
+ if (!this.get('_isRendered')) {
408
+ this._doRender();
409
+ }
408
410
 
409
411
  return this;
410
412
  },
@@ -433,7 +435,9 @@ SC.CoreView.reopen(
433
435
  this._doDetach();
434
436
  }
435
437
 
436
- this._doDestroyLayer();
438
+ if (this.get('_isRendered')) {
439
+ this._doDestroyLayer();
440
+ }
437
441
 
438
442
  return this;
439
443
  },
@@ -956,27 +960,6 @@ SC.CoreView.reopen(
956
960
  this.createChildViews(); // setup child Views
957
961
  },
958
962
 
959
- /**
960
- Wakes up the view. The default implementation immediately syncs any
961
- bindings, which may cause the view to need its display updated. You
962
- can override this method to perform any additional setup. Be sure to
963
- call sc_super to setup bindings and to call awake on childViews.
964
-
965
- It is best to awake a view before you add it to the DOM. This way when
966
- the DOM is generated, it will have the correct initial values and will
967
- not require any additional setup.
968
-
969
- @returns {void}
970
- */
971
- awake: function () {
972
- sc_super();
973
- var childViews = this.get('childViews'), len = childViews.length, idx;
974
- for (idx = 0; idx < len; ++idx) {
975
- if (!childViews[idx]) { continue; }
976
- childViews[idx].awake();
977
- }
978
- },
979
-
980
963
  /**
981
964
  Frame describes this view's current bounding rect, relative to its parent view. You
982
965
  can use this, for example, to reliably access a width for a view whose layout is
@@ -1013,12 +996,10 @@ SC.CoreView.reopen(
1013
996
  /*
1014
997
  TODO Can probably have some better width/height values - CC
1015
998
  FIXME This will probably not work right with borders - PW
1016
- FIXME This assumes and reports a scale of 1 - DCP
1017
999
  */
1018
- f.width = f.originalWidth = layer.offsetWidth;
1019
- f.height = f.originalHeight = layer.offsetHeight;
1020
- f.scale = 1;
1021
- f.transformOriginX = f.transformOriginY = 0.5;
1000
+ f.width = layer.offsetWidth;
1001
+ f.height = layer.offsetHeight;
1002
+
1022
1003
  return f;
1023
1004
  }
1024
1005
 
@@ -1031,14 +1012,12 @@ SC.CoreView.reopen(
1031
1012
  },
1032
1013
 
1033
1014
  /** @private Call the method recursively on all child views. */
1034
- _callOnChildViews: function (methodName, context) {
1015
+ _callOnChildViews: function (methodName, isTopDown, context) {
1035
1016
  var childView,
1036
1017
  childViews = this.get('childViews'),
1037
1018
  method,
1038
1019
  shouldContinue;
1039
1020
 
1040
- // Could have support for arguments, but accessing Arguments and using apply is slower than using call, so avoid it.
1041
- // args = SC.$A(arguments).slice(1);
1042
1021
  for (var i = childViews.length - 1; i >= 0; i--) {
1043
1022
  childView = childViews[i];
1044
1023
 
@@ -1047,12 +1026,20 @@ SC.CoreView.reopen(
1047
1026
 
1048
1027
  // Look up the method on the child.
1049
1028
  method = childView[methodName];
1050
- // method.apply(childView, args); This is slower.
1051
- shouldContinue = method.call(childView, context);
1029
+
1030
+ // Call the method on this view *before* its children.
1031
+ if (isTopDown === undefined || isTopDown) {
1032
+ shouldContinue = method.call(childView, context);
1033
+ }
1052
1034
 
1053
1035
  // Recurse.
1054
1036
  if (shouldContinue === undefined || shouldContinue) {
1055
- childView._callOnChildViews(methodName, context);
1037
+ childView._callOnChildViews(methodName, isTopDown, context);
1038
+ }
1039
+
1040
+ // Call the method on this view *after* its children.
1041
+ if (isTopDown === false) {
1042
+ method.call(childView, context);
1056
1043
  }
1057
1044
  }
1058
1045
  },
@@ -1074,11 +1061,10 @@ SC.CoreView.reopen(
1074
1061
  // FAST PATH: No frame, no clipping frame.
1075
1062
  if (!f) return null;
1076
1063
 
1064
+ /*jshint eqnull:true */
1077
1065
  var scale = (f.scale == null) ? 1 : f.scale,
1078
- scaleIsArray = NO,
1079
1066
  pv = this.get('parentView'),
1080
1067
  pcf = pv ? pv.get('clippingFrame') : null,
1081
- sf, spcf, originX, originY, deltaH, deltaW,
1082
1068
  ret;
1083
1069
 
1084
1070
  // FAST PATH: No parent clipping frame, no change. (The origin and scale are reset from parent view's
@@ -1142,7 +1128,9 @@ SC.CoreView.reopen(
1142
1128
  @returns {SC.View} receiver
1143
1129
  */
1144
1130
  removeChild: function (view, immediately) {
1145
- view._doDetach(immediately);
1131
+ if (view.get('isAttached')) {
1132
+ view._doDetach(immediately);
1133
+ }
1146
1134
 
1147
1135
  // If the view will transition out, wait for the transition to complete
1148
1136
  // before orphaning the view entirely.
@@ -1301,11 +1289,15 @@ SC.CoreView.reopen(
1301
1289
  } else {
1302
1290
  // Immediately remove the layer if attached (ignores transitionOut). This
1303
1291
  // will detach the layer for all child views as well.
1304
- this._doDetach(true);
1292
+ if (this.get('isAttached')) {
1293
+ this._doDetach(true);
1294
+ }
1305
1295
 
1306
1296
  // Clear the layer if rendered. This will clear all child views layer
1307
1297
  // references as well.
1308
- this._doDestroyLayer();
1298
+ if (this.get('_isRendered')) {
1299
+ this._doDestroyLayer();
1300
+ }
1309
1301
 
1310
1302
  // Complete the destroy.
1311
1303
  this._destroy();
@@ -2092,7 +2084,8 @@ SC.CoreView.unload = function () {
2092
2084
  implement mouseDown (and not return NO) in order to receive mouseUp.
2093
2085
 
2094
2086
  SproutCore implements a higher-level API for handling in-application dragging and dropping.
2095
- See `SC.Drag`, `SC.DragSource`, `SC.DragDataSource`, and `SC.DropTarget` for more.
2087
+ See `SC.Drag`, `SC.DragSourceProtocol`, `SC.DragDataSourceProtocol`, and `SC.DropTargetProtocol`
2088
+ for more.
2096
2089
 
2097
2090
  Data-drag events
2098
2091
  ----
@@ -2292,7 +2285,8 @@ SC.View = SC.CoreView.extend(/** @scope SC.View.prototype */{
2292
2285
  */
2293
2286
  computeFrameWithParentFrame: function (pdim) {
2294
2287
  // Layout.
2295
- var f, layout = this.get('layout');
2288
+ var layout = this.get('layout'),
2289
+ f;
2296
2290
 
2297
2291
  // We can't predict the frame for static layout, so just return the view's
2298
2292
  // current frame (see original computeFrameWithParentFrame in views/view.js)
@@ -2306,8 +2300,6 @@ SC.View = SC.CoreView.extend(/** @scope SC.View.prototype */{
2306
2300
  f = {};
2307
2301
 
2308
2302
  var error, layer, AUTO = SC.LAYOUT_AUTO,
2309
- pv = this.get('parentView'),
2310
- scale, oX, oY, // Used with the special case ScrollView handling below.
2311
2303
  dH, dW, //shortHand for parentDimensions
2312
2304
  lR = layout.right,
2313
2305
  lL = layout.left,
@@ -2319,15 +2311,13 @@ SC.View = SC.CoreView.extend(/** @scope SC.View.prototype */{
2319
2311
  lcY = layout.centerY;
2320
2312
 
2321
2313
  if (lW === AUTO) {
2322
- error = SC.Error.desc(("%@.layout() cannot use width:auto if " +
2323
- "staticLayout is disabled").fmt(this), "%@".fmt(this), -1);
2314
+ error = SC.Error.desc(("%@.layout() cannot use width:auto if staticLayout is disabled").fmt(this), "%@".fmt(this), -1);
2324
2315
  SC.Logger.error(error.toString());
2325
2316
  throw error;
2326
2317
  }
2327
2318
 
2328
2319
  if (lH === AUTO) {
2329
- error = SC.Error.desc(("%@.layout() cannot use height:auto if " +
2330
- "staticLayout is disabled").fmt(this), "%@".fmt(this), -1);
2320
+ error = SC.Error.desc(("%@.layout() cannot use height:auto if staticLayout is disabled").fmt(this), "%@".fmt(this), -1);
2331
2321
  SC.Logger.error(error.toString());
2332
2322
  throw error;
2333
2323
  }
@@ -2343,6 +2333,7 @@ SC.View = SC.CoreView.extend(/** @scope SC.View.prototype */{
2343
2333
  } else {
2344
2334
  f.x = lL;
2345
2335
  }
2336
+
2346
2337
  if (lW !== undefined) {
2347
2338
  if (lW === AUTO) { f.width = AUTO; }
2348
2339
  else if (SC.isPercentage(lW)) { f.width = dW * lW; }
@@ -2352,6 +2343,7 @@ SC.View = SC.CoreView.extend(/** @scope SC.View.prototype */{
2352
2343
  if (lR && SC.isPercentage(lR)) { f.width = f.width - (lR * dW); }
2353
2344
  else { f.width = f.width - (lR || 0); }
2354
2345
  }
2346
+
2355
2347
  // handle right aligned
2356
2348
  } else if (!SC.none(lR)) {
2357
2349
  if (SC.none(lW)) {
@@ -2451,13 +2443,14 @@ SC.View = SC.CoreView.extend(/** @scope SC.View.prototype */{
2451
2443
  f = this._adjustForBorder(f, layout);
2452
2444
 
2453
2445
  // Make sure the width/height fix their min/max (note the inlining of SC.none for performance)...
2446
+ /*jshint eqnull:true */
2454
2447
  if ((layout.maxHeight != null) && (f.height > layout.maxHeight)) f.height = layout.maxHeight;
2455
2448
  if ((layout.minHeight != null) && (f.height < layout.minHeight)) f.height = layout.minHeight;
2456
2449
  if ((layout.maxWidth != null) && (f.width > layout.maxWidth)) f.width = layout.maxWidth;
2457
2450
  if ((layout.minWidth != null) && (f.width < layout.minWidth)) f.width = layout.minWidth;
2458
2451
 
2459
- // Finally, adjust for scale. (Scale is only defined here if we're doing special-case ScrollView stuff.)
2460
- f = this._adjustForScale(f, layout, scale, oX, oY);
2452
+ // Finally, adjust for scale.
2453
+ f = this._adjustForScale(f, layout);
2461
2454
 
2462
2455
  return f;
2463
2456
  },
@@ -327,13 +327,13 @@ SC.View.reopen(
327
327
 
328
328
  // Get the layout (may be a previous layout already animating).
329
329
  if (!this._prevLayout) {
330
- this._prevLayout = SC.clone(this.get('layout'));
330
+ this._prevLayout = SC.clone(this.get('explicitLayout'));
331
331
  }
332
332
 
333
333
  if (!pendingAnimations) { pendingAnimations = this._pendingAnimations = {}; }
334
334
 
335
335
  // Get the layout (may be a partially adjusted one already queued up).
336
- layout = this._animateLayout || SC.clone(this.get('layout'));
336
+ layout = this._animateLayout || SC.clone(this.get('explicitLayout'));
337
337
 
338
338
  // Handle old style rotation.
339
339
  if (!SC.none(hash.rotate)) {
@@ -542,7 +542,7 @@ SC.View.reopen(
542
542
 
543
543
  // Adjust to final position.
544
544
  if (didCancel && !!layout) {
545
- this.adjust(layout);
545
+ this.set('layout', layout);
546
546
  }
547
547
 
548
548
  // Clean up.
@@ -633,8 +633,7 @@ SC.View.reopen(
633
633
  components = matrixString.split(/\(|\)/);
634
634
  numbers = components[1].split(',');
635
635
  for (var i = 0, len = numbers.length; i < len; i++) {
636
- var number = numbers[i],
637
- value;
636
+ var number = numbers[i];
638
637
 
639
638
  // Transform E notation into fixed decimal (20 is maximum allowed).
640
639
  if (number.indexOf('e') > 0) {
@@ -744,7 +743,7 @@ SC.View.reopen(
744
743
 
745
744
  // Determine the current style.
746
745
  } else {
747
- value = window.parseInt(value, 10);
746
+ value = window.parseFloat(value, 10);
748
747
 
749
748
  // Account for centerX & centerY animations (margin-left & margin-top).
750
749
  if (key === 'centerX') {