sproutcore 1.11.0.rc1 → 1.11.0.rc2
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.
- checksums.yaml +8 -8
- data/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +93 -65
- data/lib/frameworks/sproutcore/apps/showcase/controllers/source_tree_controller.js +17 -7
- data/lib/frameworks/sproutcore/apps/showcase/resources/main_page.js +22 -2
- data/lib/frameworks/sproutcore/apps/showcase/resources/stylesheet.css +14 -0
- data/lib/frameworks/sproutcore/apps/showcase/resources/views_page.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +20 -8
- data/lib/frameworks/sproutcore/frameworks/ajax/system/websocket.js +58 -43
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +192 -35
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/delegate_support.js +7 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +27 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/browser.js +20 -63
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/color.js +16 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +279 -159
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +21 -10
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/action_support.js +32 -28
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/targetForAction.js +107 -90
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/touch.js +33 -25
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/touch.js +23 -15
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +12 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +55 -33
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +7 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/methods.js +228 -72
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/touch.js +54 -100
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +15 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +57 -45
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +9 -16
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll_view.js +111 -44
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +51 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +13 -10
- data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +28 -9
- data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +7 -5
- data/lib/frameworks/sproutcore/frameworks/statechart/ext/function.js +51 -46
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +8 -5
- data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +12 -3
- metadata +2 -2
data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/touch.js
CHANGED
@@ -40,35 +40,40 @@ module("SC.RootResponder", {
|
|
40
40
|
evt2.changedTouches.push(evt);
|
41
41
|
evt2.changedTouches.push(evt2);
|
42
42
|
},
|
43
|
-
|
43
|
+
|
44
44
|
teardown: function() {
|
45
45
|
pane.destroy();
|
46
|
+
evt = evt2 = layer = view = pane = null;
|
46
47
|
}
|
47
48
|
});
|
48
49
|
|
49
50
|
// With v1.11, SC.Touch now provides its own velocity along each axis.
|
50
51
|
test("SC.Touch velocity", function() {
|
51
52
|
// Get a layer
|
52
|
-
var touch
|
53
|
+
var touch,
|
54
|
+
lastTimestamp;
|
55
|
+
|
56
|
+
lastTimestamp = evt.timeStamp;
|
53
57
|
|
54
58
|
// Trigger touchstart
|
55
|
-
SC.
|
56
|
-
SC.Event.trigger(layer, 'touchstart', [evt]);
|
57
|
-
});
|
59
|
+
SC.Event.trigger(layer, 'touchstart', [evt]);
|
58
60
|
|
59
61
|
touch = SC.RootResponder.responder._touches[evt.identifier];
|
60
62
|
|
61
63
|
equals(touch.velocityX, 0, "Horizontal velocity begin at zero");
|
62
64
|
equals(touch.velocityY, 0, "Vertical velocity begin at zero");
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
SC.
|
70
|
-
|
71
|
-
|
66
|
+
// Copy the last DOM touch as the basis of an updated DOM touch.
|
67
|
+
touch = SC.copy(touch);
|
68
|
+
touch.pageX += 100;
|
69
|
+
touch.pageY += 100;
|
70
|
+
|
71
|
+
evt = SC.Event.simulateEvent(layer, 'touchmove', { touches: [touch], identifier: 4, changedTouches: [touch] });
|
72
|
+
evt.timeStamp = lastTimestamp + 100;
|
73
|
+
|
74
|
+
SC.Event.trigger(layer, 'touchmove', [evt]);
|
75
|
+
|
76
|
+
touch = SC.RootResponder.responder._touches[evt.identifier];
|
72
77
|
|
73
78
|
equals(touch.velocityX, 1, 'VelocityX for 100 pixels in 100 ms is 1.');
|
74
79
|
equals(touch.velocityY, 1, 'VelocityY for 100 pixels in 100 ms is 1.');
|
@@ -77,13 +82,15 @@ test("SC.Touch velocity", function() {
|
|
77
82
|
|
78
83
|
test("averagedTouchesForView", function() {
|
79
84
|
// Start touch.
|
80
|
-
SC.
|
81
|
-
|
82
|
-
|
85
|
+
SC.Event.trigger(layer, 'touchstart', evt);
|
86
|
+
|
87
|
+
// Copy the last DOM touch as the basis of an updated DOM touch.
|
88
|
+
var touch1 = SC.RootResponder.responder._touches[evt.identifier];
|
89
|
+
var touch2 = SC.RootResponder.responder._touches[evt2.identifier];
|
83
90
|
|
84
91
|
// Get our starting average.
|
85
|
-
var expectedAverageX = (
|
86
|
-
expectedAverageY = (
|
92
|
+
var expectedAverageX = (touch1.pageX + touch2.pageX) / 2,
|
93
|
+
expectedAverageY = (touch1.pageY + touch2.pageY) / 2,
|
87
94
|
startAverage = SC.clone(SC.RootResponder.responder.averagedTouchesForView(view));
|
88
95
|
|
89
96
|
equals(startAverage.x, expectedAverageX, "averagedTouchesForView correctly returns touch location averages (x)");
|
@@ -91,13 +98,14 @@ test("averagedTouchesForView", function() {
|
|
91
98
|
ok(startAverage.d, "averagedTouchesForView's distance measurement should ... be a nonzero number. (Pythagoras doesn't play nice with integers.)");
|
92
99
|
|
93
100
|
// Pinch out by 50 pixels in every direction.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
+
touch1.pageX = 50;
|
102
|
+
touch1.pageY = 50;
|
103
|
+
touch2.pageX = 250;
|
104
|
+
touch2.pageY = 250;
|
105
|
+
|
106
|
+
var moveEvt = SC.Event.simulateEvent(layer, 'touchmove', { touches: [touch1, touch2], identifier: 6, changedTouches: [touch1, touch2] });
|
107
|
+
SC.Event.trigger(layer, 'touchmove', moveEvt);
|
108
|
+
|
101
109
|
// Get our post-pinch average.
|
102
110
|
var endAverage = SC.RootResponder.responder.averagedTouchesForView(view);
|
103
111
|
|
@@ -65,16 +65,15 @@ test("Touch event handling and juggling.", function() {
|
|
65
65
|
var outer = pane.outerView,
|
66
66
|
inner = outer.innerView,
|
67
67
|
layer = inner.get('layer'),
|
68
|
-
event = SC.Event.simulateEvent(layer, 'touchstart')
|
68
|
+
event = SC.Event.simulateEvent(layer, 'touchstart'),
|
69
|
+
touch;
|
69
70
|
|
70
71
|
event.touches = [];
|
71
72
|
event.identifier = 4;
|
72
73
|
event.changedTouches = [event];
|
73
74
|
|
74
75
|
// Trigger touchstart: outerView.captureTouch > outerView.touchStart
|
75
|
-
SC.
|
76
|
-
SC.Event.trigger(layer, 'touchstart', [event]);
|
77
|
-
});
|
76
|
+
SC.Event.trigger(layer, 'touchstart', [event]);
|
78
77
|
|
79
78
|
equals(outerCapture, 1, "To capture the initial touch, outerView.captureTouch should have run:");
|
80
79
|
equals(outerStart, 1, "Having captured the initial touch, outerView.touchStart should have run:");
|
@@ -87,10 +86,13 @@ test("Touch event handling and juggling.", function() {
|
|
87
86
|
if (outerEnd) ok(false, "outerView.touchEnd should not have been called yet!");
|
88
87
|
|
89
88
|
// Trigger touchmoved: outerView.touchesDragged > [passes touch to innerView] > innerView.touchStart
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
89
|
+
|
90
|
+
// Copy the last DOM touch as the basis of an updated DOM touch.
|
91
|
+
touch = SC.RootResponder.responder._touches[event.identifier];
|
92
|
+
touch = SC.copy(touch);
|
93
|
+
|
94
|
+
event = SC.Event.simulateEvent(layer, 'touchmove', { touches: [touch], identifier: 4, changedTouches: [touch] });
|
95
|
+
SC.Event.trigger(layer, 'touchmove', [event]);
|
94
96
|
|
95
97
|
if (outerCapture !== 1) ok(false, "outerView.captureTouch should only have been called once!");
|
96
98
|
if (outerStart !== 1) ok(false, "outerView.touchStart should only have been called once!");
|
@@ -103,9 +105,12 @@ test("Touch event handling and juggling.", function() {
|
|
103
105
|
if (outerEnd) ok(false, "outerView.touchEnd should not have been called yet!");
|
104
106
|
|
105
107
|
// Trigger touchmoved x2: innerView.touchesDragged > [passes touch back to outerView] > outerView.touchStart > innerView.touchCancelled
|
106
|
-
|
107
|
-
|
108
|
-
|
108
|
+
// Copy the last DOM touch as the basis of an updated DOM touch.
|
109
|
+
touch = SC.RootResponder.responder._touches[event.identifier];
|
110
|
+
touch = SC.copy(touch);
|
111
|
+
|
112
|
+
event = SC.Event.simulateEvent(layer, 'touchmove', { touches: [touch], identifier: 4, changedTouches: [touch] });
|
113
|
+
SC.Event.trigger(layer, 'touchmove', [event]);
|
109
114
|
|
110
115
|
if (outerCapture !== 1) ok(false, "outerView.captureTouch should only have been called once!");
|
111
116
|
equals(outerDragged, 1, "Having passed ownership to innerView, outerView.touchesDragged should not have been called again:");
|
@@ -118,10 +123,13 @@ test("Touch event handling and juggling.", function() {
|
|
118
123
|
if (outerEnd) ok(false, "outerView.touchEnd should not have been called yet!");
|
119
124
|
|
120
125
|
// Trigger touchend: outerView.touchEnd
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
126
|
+
|
127
|
+
// Copy the last DOM touch as the basis of an updated DOM touch.
|
128
|
+
touch = SC.RootResponder.responder._touches[event.identifier];
|
129
|
+
touch = SC.copy(touch);
|
130
|
+
|
131
|
+
event = SC.Event.simulateEvent(layer, 'touchend', { touches: [touch], identifier: 4, changedTouches: [touch] });
|
132
|
+
SC.Event.trigger(layer, 'touchend', [event]);
|
125
133
|
|
126
134
|
if (outerCapture !== 1) ok(false, "outerView.captureTouch should only have been called once!");
|
127
135
|
if (outerStart !== 1) ok(false, "outerView.touchStart should only have been called once!");
|
@@ -189,7 +189,7 @@ SC.View.reopen(
|
|
189
189
|
);
|
190
190
|
|
191
191
|
The animate functions are intelligent in how they apply animations and
|
192
|
-
calling animate in a manner that would
|
192
|
+
calling animate in a manner that would affect an ongoing animation (i.e.
|
193
193
|
animating left again while it is still in transition) will result in
|
194
194
|
the ongoing animation callback firing immediately with isCancelled set to
|
195
195
|
true and adjusting the transition to accomodate the new settings.
|
@@ -145,6 +145,7 @@ SC.View.reopen(
|
|
145
145
|
}
|
146
146
|
|
147
147
|
// Ignore undefined values or values equal to the current value.
|
148
|
+
/*jshint eqeqeq:false*/
|
148
149
|
if (newValue !== undefined && layout[key] != newValue) { // coerced so '100' == 100
|
149
150
|
// Only clone the layout if it is not given.
|
150
151
|
if (!newLayout) newLayout = SC.clone(this.get('layout'));
|
@@ -543,13 +544,16 @@ SC.View.reopen(
|
|
543
544
|
// Add the original, unscaled height and width.
|
544
545
|
frame.originalWidth = originalWidth;
|
545
546
|
frame.originalHeight = originalHeight;
|
547
|
+
|
546
548
|
return frame;
|
547
549
|
}
|
550
|
+
|
548
551
|
// Get the scale and transform origins, if not provided. (Note inlining of SC.none for performance)
|
549
552
|
/*jshint eqnull:true*/
|
550
553
|
scale = scale == null ? layout.scale : scale;
|
551
554
|
oX = oX == null ? layout.transformOriginX : oX;
|
552
555
|
oY = oY == null ? layout.transformOriginY : oY;
|
556
|
+
|
553
557
|
// Get defaults.
|
554
558
|
if (scale == null) scale = 1;
|
555
559
|
if (oX == null) oX = 0.5;
|
@@ -559,6 +563,7 @@ SC.View.reopen(
|
|
559
563
|
if (scale !== 1) {
|
560
564
|
frame = SC.scaleRect(frame, scale, oX, oY);
|
561
565
|
}
|
566
|
+
|
562
567
|
// Regardless, attach the scale numbers for reference.
|
563
568
|
frame.scale = scale;
|
564
569
|
frame.transformOriginX = oX;
|
@@ -797,8 +802,8 @@ SC.View.reopen(
|
|
797
802
|
if (!SC.none(currentLayout.rotate)) {
|
798
803
|
if (SC.none(currentLayout.rotateZ) && SC.platform.get('supportsCSS3DTransforms')) {
|
799
804
|
currentLayout.rotateZ = currentLayout.rotate;
|
800
|
-
|
801
|
-
|
805
|
+
delete currentLayout.rotate;
|
806
|
+
}
|
802
807
|
}
|
803
808
|
|
804
809
|
// Optimize notifications depending on if we resized or just moved.
|
@@ -1139,11 +1144,12 @@ SC.View.reopen(
|
|
1139
1144
|
|
1140
1145
|
/** @private */
|
1141
1146
|
_doUpdateLayoutStyle: function () {
|
1142
|
-
var
|
1147
|
+
var layer = this.get('layer'),
|
1148
|
+
layoutStyle = this.get('layoutStyle');
|
1143
1149
|
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1150
|
+
for (var styleName in layoutStyle) {
|
1151
|
+
layer.style[styleName] = layoutStyle[styleName];
|
1152
|
+
}
|
1147
1153
|
|
1148
1154
|
// Reset that an update is required.
|
1149
1155
|
this._layoutStyleNeedsUpdate = false;
|
@@ -11,6 +11,7 @@ sc_require('views/view/animation');
|
|
11
11
|
SC.CSS_TRANSFORM_NAMES = ['rotateX', 'rotateY', 'rotateZ', 'scale'];
|
12
12
|
|
13
13
|
SC.CSS_TRANSFORM_MAP = {
|
14
|
+
|
14
15
|
rotate: function (val) {
|
15
16
|
if (SC.typeOf(val) === SC.T_NUMBER) { val += 'deg'; }
|
16
17
|
return 'rotate(' + val + ')';
|
@@ -41,21 +42,30 @@ SC.CSS_TRANSFORM_MAP = {
|
|
41
42
|
/** @private */
|
42
43
|
SC.View.LayoutStyleCalculator = {
|
43
44
|
|
45
|
+
/** @private Shared object used to avoid continually initializing/destroying objects. */
|
46
|
+
_SC_STATE_MAP: null,
|
47
|
+
|
48
|
+
/** @private Shared object used to avoid continually initializing/destroying objects. */
|
49
|
+
_SC_TRANSFORMS_ARRAY: null,
|
50
|
+
|
51
|
+
/** @private Shared object used to avoid continually initializing/destroying objects. */
|
52
|
+
_SC_TRANSITIONS_ARRAY: null,
|
53
|
+
|
44
54
|
/** @private If the value is undefined, make it null. */
|
45
55
|
_valueOrNull: function (value) {
|
46
56
|
return value === undefined ? null : value;
|
47
57
|
},
|
48
58
|
|
49
59
|
/** @private */
|
50
|
-
_prepareStyle: function (layout) {
|
60
|
+
_prepareStyle: function (style, layout) {
|
51
61
|
/*jshint eqnull:true */
|
52
62
|
// It's important to provide null defaults to reset any previous style when
|
53
63
|
// this is applied.
|
54
|
-
var commonBorder = this._valueOrNull(layout.border)
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
64
|
+
var commonBorder = this._valueOrNull(layout.border);
|
65
|
+
|
66
|
+
// Reset properties that might not be set from style to style.
|
67
|
+
style.marginLeft = null;
|
68
|
+
style.marginTop = null;
|
59
69
|
|
60
70
|
// Position and size.
|
61
71
|
style.bottom = layout.bottom;
|
@@ -88,9 +98,12 @@ SC.View.LayoutStyleCalculator = {
|
|
88
98
|
// Handle transforms (including reset).
|
89
99
|
if (SC.platform.supportsCSSTransforms) {
|
90
100
|
var transformAttribute = SC.browser.experimentalStyleNameFor('transform'),
|
91
|
-
transforms =
|
101
|
+
transforms = this._SC_TRANSFORMS_ARRAY, // Shared object used to avoid continually initializing/destroying objects.
|
92
102
|
transformMap = SC.CSS_TRANSFORM_MAP;
|
93
103
|
|
104
|
+
// Create the array once. Note: This is a shared array; it must be set to 0 length each time.
|
105
|
+
if (!transforms) { transforms = this._SC_TRANSFORMS_ARRAY = []; }
|
106
|
+
|
94
107
|
// The order of the transforms is important so that we can decompose them
|
95
108
|
// from the transformation matrix later if necessary.
|
96
109
|
for (var i = 0, len = SC.CSS_TRANSFORM_NAMES.length; i < len; i++) {
|
@@ -103,6 +116,7 @@ SC.View.LayoutStyleCalculator = {
|
|
103
116
|
}
|
104
117
|
}
|
105
118
|
|
119
|
+
// Set or reset the transform style.
|
106
120
|
style[transformAttribute] = transforms.length > 0 ? transforms.join(' ') : null;
|
107
121
|
|
108
122
|
// Transform origin.
|
@@ -123,24 +137,13 @@ SC.View.LayoutStyleCalculator = {
|
|
123
137
|
style[SC.browser.experimentalStyleNameFor('transition')] = null;
|
124
138
|
}
|
125
139
|
|
126
|
-
//
|
127
|
-
|
128
|
-
// useless for most SC purposes.
|
129
|
-
//
|
130
|
-
// b) It completely breaks semitransparent background images (PNGs with opacity)
|
131
|
-
//
|
132
|
-
// If users want to use alpha, they should do it on their own.
|
133
|
-
|
134
|
-
// if(!SC.none(layout.opacity)) style.filter = "alpha(opacity=%@)".fmt(layout.opacity * 100);
|
135
|
-
|
136
|
-
return style;
|
140
|
+
// Reset shared object!
|
141
|
+
this._SC_TRANSFORMS_ARRAY.length = 0;
|
137
142
|
},
|
138
143
|
|
139
144
|
/** @private */
|
140
|
-
_prepareState: function (style) {
|
145
|
+
_prepareState: function (state, style) {
|
141
146
|
/*jshint eqnull:true */
|
142
|
-
var state = {};
|
143
|
-
|
144
147
|
state.hasBottom = (style.bottom != null);
|
145
148
|
state.hasRight = (style.right != null);
|
146
149
|
state.hasLeft = (style.left != null);
|
@@ -151,8 +154,6 @@ SC.View.LayoutStyleCalculator = {
|
|
151
154
|
state.hasWidth = (style.width != null);
|
152
155
|
state.hasMaxWidth = (style.maxWidth != null);
|
153
156
|
state.hasMaxHeight = (style.maxHeight != null);
|
154
|
-
|
155
|
-
return state;
|
156
157
|
},
|
157
158
|
|
158
159
|
|
@@ -277,7 +278,7 @@ SC.View.LayoutStyleCalculator = {
|
|
277
278
|
},
|
278
279
|
|
279
280
|
/** @private */
|
280
|
-
// return "auto" for "auto", null for null, converts 0.
|
281
|
+
// return "auto" for "auto", null for null, converts 0.X into "X%".
|
281
282
|
// otherwise returns the original number, rounded down
|
282
283
|
_cssNumber: function (val) {
|
283
284
|
/*jshint eqnull:true*/
|
@@ -293,12 +294,11 @@ SC.View.LayoutStyleCalculator = {
|
|
293
294
|
|
294
295
|
@return {Object} Layout style hash.
|
295
296
|
*/
|
296
|
-
calculate: function (view) {
|
297
|
+
calculate: function (view, style) {
|
297
298
|
var layout = view.get('layout'),
|
298
299
|
animations = view._activeAnimations,
|
299
|
-
state,
|
300
|
-
useStaticLayout = view.get('useStaticLayout')
|
301
|
-
style;
|
300
|
+
state = this._SC_STATE_MAP, // Shared object used to avoid continually initializing/destroying objects.
|
301
|
+
useStaticLayout = view.get('useStaticLayout');
|
302
302
|
|
303
303
|
// Fast path!
|
304
304
|
// If the developer sets useStaticLayout and doesn't provide a unique `layout` property, we
|
@@ -307,8 +307,14 @@ SC.View.LayoutStyleCalculator = {
|
|
307
307
|
// use it.
|
308
308
|
if (useStaticLayout && layout === SC.View.prototype.layout) { return {}; }
|
309
309
|
|
310
|
-
style
|
311
|
-
|
310
|
+
// Reset and prep the style object.
|
311
|
+
this._prepareStyle(style, layout);
|
312
|
+
|
313
|
+
// Create the object once. Note: This is a shared object; all properties must be overwritten each time.
|
314
|
+
if (!state) { state = this._SC_STATE_MAP = {}; }
|
315
|
+
|
316
|
+
// Reset and prep the state object.
|
317
|
+
this._prepareState(state, style);
|
312
318
|
|
313
319
|
// handle invalid use of auto in absolute layouts
|
314
320
|
if (!useStaticLayout) {
|
@@ -389,7 +395,10 @@ SC.View.LayoutStyleCalculator = {
|
|
389
395
|
// Handle animations
|
390
396
|
if (animations) {
|
391
397
|
if (SC.platform.supportsCSSTransitions) {
|
392
|
-
var transitions =
|
398
|
+
var transitions = this._SC_TRANSITIONS_ARRAY; // Shared object used to avoid continually initializing/destroying objects.
|
399
|
+
|
400
|
+
// Create the array once. Note: This is a shared array; it must be set to 0 length each time.
|
401
|
+
if (!transitions) { transitions = this._SC_TRANSITIONS_ARRAY = []; }
|
393
402
|
|
394
403
|
for (key in animations) {
|
395
404
|
var animation = animations[key],
|
@@ -436,6 +445,9 @@ SC.View.LayoutStyleCalculator = {
|
|
436
445
|
}
|
437
446
|
|
438
447
|
style[SC.browser.experimentalStyleNameFor('transition')] = transitions.join(", ");
|
448
|
+
|
449
|
+
// Reset shared object!
|
450
|
+
this._SC_TRANSITIONS_ARRAY.length = 0;
|
439
451
|
} else {
|
440
452
|
// TODO: Do it the JS way
|
441
453
|
}
|
@@ -449,6 +461,9 @@ SC.View.LayoutStyleCalculator = {
|
|
449
461
|
SC.View.reopen(
|
450
462
|
/** @scope SC.View.prototype */ {
|
451
463
|
|
464
|
+
/** @private Shared object used to avoid continually initializing/destroying objects. */
|
465
|
+
_SC_STYLE_MAP: null,
|
466
|
+
|
452
467
|
/**
|
453
468
|
layoutStyle describes the current styles to be written to your element
|
454
469
|
based on the layout you defined. Both layoutStyle and frame reset when
|
@@ -460,7 +475,14 @@ SC.View.reopen(
|
|
460
475
|
@readOnly
|
461
476
|
*/
|
462
477
|
layoutStyle: function () {
|
463
|
-
|
464
|
-
|
478
|
+
var style = this._SC_STYLE_MAP; // Shared object used to avoid continually initializing/destroying objects.
|
479
|
+
|
480
|
+
// Create the object once. Note: This is a shared object; all properties must be overwritten each time.
|
481
|
+
if (!style) { style = this._SC_STYLE_MAP = {}; }
|
482
|
+
|
483
|
+
return SC.View.LayoutStyleCalculator.calculate(this, style);
|
484
|
+
|
485
|
+
// 'hasAcceleratedLayer' is dependent on 'layout' so we don't need 'layout' to be a dependency here
|
465
486
|
}.property('hasAcceleratedLayer', 'useStaticLayout').cacheable()
|
487
|
+
|
466
488
|
});
|
@@ -109,7 +109,13 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
109
109
|
@returns {SC.Store} receiver
|
110
110
|
*/
|
111
111
|
cascade: function(dataSource) {
|
112
|
-
var dataSources
|
112
|
+
var dataSources;
|
113
|
+
|
114
|
+
// Fast arguments access.
|
115
|
+
// Accessing `arguments.length` is just a Number and doesn't materialize the `arguments` object, which is costly.
|
116
|
+
dataSources = new Array(arguments.length); // SC.A(arguments)
|
117
|
+
for (var i = 0, len = dataSources.length; i < len; i++) { dataSources[i] = arguments[i]; }
|
118
|
+
|
113
119
|
dataSource = SC.CascadeDataSource.create({
|
114
120
|
dataSources: dataSources
|
115
121
|
});
|
@@ -91,7 +91,7 @@ module("SC.ScrollView", {
|
|
91
91
|
SC.run(function () {
|
92
92
|
pane.destroy();
|
93
93
|
});
|
94
|
-
pane = view = null;
|
94
|
+
pane = view = view2 = view3 = view4 = null;
|
95
95
|
}
|
96
96
|
});
|
97
97
|
|
@@ -117,6 +117,194 @@ test("Scrolling to a certain co-ordinate of the container view", function () {
|
|
117
117
|
});
|
118
118
|
});
|
119
119
|
|
120
|
+
|
121
|
+
test("Scroll offsets are correct when scroll view's frame changes", function () {
|
122
|
+
|
123
|
+
// Scenario: left & top aligned, at maximums, scroll view shrinks: don't move content
|
124
|
+
SC.run(function () {
|
125
|
+
view.scrollBy(3900, 3900);
|
126
|
+
pane.adjust({ width: 64, height: 64 });
|
127
|
+
equals(view.get('horizontalScrollOffset'), 3900, "After resizing the pane with adjust height of 64, horizontal offset must not change");
|
128
|
+
equals(view.get('verticalScrollOffset'), 3900, "After resizing the pane with adjust width of 64, vertical offset must not change");
|
129
|
+
});
|
130
|
+
|
131
|
+
// Reset the parent view.
|
132
|
+
SC.run(function () {
|
133
|
+
view.scrollTo(0, 0);
|
134
|
+
pane.adjust({ width: 114, height: 114 });
|
135
|
+
});
|
136
|
+
|
137
|
+
// Scenario: left & top aligned, at maximums, scroll view grows: hug the right & bottom sides.
|
138
|
+
SC.run(function () {
|
139
|
+
view.scrollBy(3900, 3900);
|
140
|
+
pane.adjust({ width: 1014, height: 1014 });
|
141
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset'), "After resizing the pane with adjust height of 1014, horizontal offset must be maximum");
|
142
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset'), "After resizing the pane with adjust width of 1014, vertical offset must be maximum");
|
143
|
+
});
|
144
|
+
|
145
|
+
// Reset the parent view.
|
146
|
+
SC.run(function () {
|
147
|
+
view.scrollTo(0, 0);
|
148
|
+
pane.adjust({ width: 114, height: 114 });
|
149
|
+
});
|
150
|
+
|
151
|
+
// Set alignments to hug right and bottom edges.
|
152
|
+
SC.run(function() {
|
153
|
+
view.set('horizontalAlign', SC.ALIGN_RIGHT);
|
154
|
+
view.set('verticalAlign', SC.ALIGN_BOTTOM);
|
155
|
+
});
|
156
|
+
|
157
|
+
// Scenario: right & bottom aligned, at maximums, scroll view shrinks: hug the right & bottom sides.
|
158
|
+
SC.run(function () {
|
159
|
+
view.scrollBy(3900, 3900);
|
160
|
+
pane.adjust({ width: 64, height: 64 });
|
161
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset'), "After resizing the pane with adjust height of 64, horizontal offset must be maximum");
|
162
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset'), "After resizing the pane with adjust width of 64, vertical offset must be maximum");
|
163
|
+
});
|
164
|
+
|
165
|
+
// Reset the parent view.
|
166
|
+
SC.run(function () {
|
167
|
+
view.scrollTo(0, 0);
|
168
|
+
pane.adjust({ width: 114, height: 114 });
|
169
|
+
});
|
170
|
+
|
171
|
+
// Scenario: right & bottom aligned, at maximums, scroll view grows: hug the right & bottom sides.
|
172
|
+
SC.run(function () {
|
173
|
+
view.scrollBy(3900, 3900);
|
174
|
+
pane.adjust({ width: 1014, height: 1014 });
|
175
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset'), "After resizing the pane with adjust height of 1014, horizontal offset must be maximum");
|
176
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset'), "After resizing the pane with adjust width of 1014, vertical offset must be maximum");
|
177
|
+
});
|
178
|
+
|
179
|
+
// Reset the parent view.
|
180
|
+
SC.run(function () {
|
181
|
+
view.scrollTo(0, 0);
|
182
|
+
pane.adjust({ width: 114, height: 114 });
|
183
|
+
});
|
184
|
+
|
185
|
+
// Set alignments to be center and middle.
|
186
|
+
SC.run(function() {
|
187
|
+
view.set('horizontalAlign', SC.ALIGN_CENTER);
|
188
|
+
view.set('verticalAlign', SC.ALIGN_MIDDLE);
|
189
|
+
});
|
190
|
+
|
191
|
+
// Scenario: center & middle aligned, at center & middle, scroll view shrinks: stick to center & middle
|
192
|
+
SC.run(function () {
|
193
|
+
view.scrollBy(1950, 1950);
|
194
|
+
pane.adjust({ width: 64, height: 64 });
|
195
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset') / 2, "After resizing the pane with adjust height of 64, horizontal offset should stay centered");
|
196
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset') / 2, "After resizing the pane with adjust width of 64, vertical offset should stay centered");
|
197
|
+
});
|
198
|
+
|
199
|
+
// Reset the parent view.
|
200
|
+
SC.run(function () {
|
201
|
+
view.scrollTo(0, 0);
|
202
|
+
pane.adjust({ width: 114, height: 114 });
|
203
|
+
});
|
204
|
+
|
205
|
+
// Scenario: center & middle aligned, at center & middle, scroll view grows: stick to center & middle
|
206
|
+
SC.run(function () {
|
207
|
+
view.scrollBy(1950, 1950);
|
208
|
+
pane.adjust({ width: 1014, height: 1014 });
|
209
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset') / 2, "After resizing the pane with adjust height of 1014, horizontal offset should stay centered");
|
210
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset') / 2, "After resizing the pane with adjust width of 1014, vertical offset should stay centered");
|
211
|
+
});
|
212
|
+
});
|
213
|
+
|
214
|
+
test("Scroll offsets are correct when scroll view's content frame changes", function () {
|
215
|
+
var contentView = view.get('contentView');
|
216
|
+
|
217
|
+
// Scenario: left & top aligned, at maximums, content view shrinks: hug the right & bottom sides
|
218
|
+
SC.run(function () {
|
219
|
+
view.scrollBy(3900, 3900);
|
220
|
+
contentView.adjust({ width: 3900, height: 3900 });
|
221
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset'), "After resizing the content with adjust width of 3900, horizontal offset must be at maximum");
|
222
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset'), "After resizing the content with adjust height of 3900 vertical offset must be at maximum");
|
223
|
+
});
|
224
|
+
|
225
|
+
// Reset the view.
|
226
|
+
SC.run(function () {
|
227
|
+
view.scrollTo(0, 0);
|
228
|
+
contentView.adjust({ width: 4000, height: 4000 });
|
229
|
+
});
|
230
|
+
|
231
|
+
// Scenario: left & top aligned, at maximums, content view grows: don't move
|
232
|
+
SC.run(function () {
|
233
|
+
view.scrollBy(3900, 3900);
|
234
|
+
contentView.adjust({ width: 4100, height: 4100 });
|
235
|
+
equals(view.get('horizontalScrollOffset'), 3900, "After resizing the content with adjust width of 4100, horizontal offset must not change");
|
236
|
+
equals(view.get('verticalScrollOffset'), 3900, "After resizing the content with adjust height of 4100, vertical offset must not change");
|
237
|
+
});
|
238
|
+
|
239
|
+
// Reset the view.
|
240
|
+
SC.run(function () {
|
241
|
+
view.scrollTo(0, 0);
|
242
|
+
contentView.adjust({ width: 4000, height: 4000 });
|
243
|
+
});
|
244
|
+
|
245
|
+
// Set alignments to hug right and bottom edges.
|
246
|
+
SC.run(function() {
|
247
|
+
view.set('horizontalAlign', SC.ALIGN_RIGHT);
|
248
|
+
view.set('verticalAlign', SC.ALIGN_BOTTOM);
|
249
|
+
});
|
250
|
+
|
251
|
+
// Scenario: right & bottom aligned, at maximums, content view shrinks: hug the right & bottom sides.
|
252
|
+
SC.run(function () {
|
253
|
+
view.scrollBy(3900, 3900);
|
254
|
+
contentView.adjust({ width: 3900, height: 3900 });
|
255
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset'), "After resizing the content with adjust width of 3900, horizontal offset must be at maximum");
|
256
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset'), "After resizing the content with adjust height of 3900 vertical offset must be at maximum");
|
257
|
+
});
|
258
|
+
|
259
|
+
// Reset the view.
|
260
|
+
SC.run(function () {
|
261
|
+
view.scrollTo(0, 0);
|
262
|
+
contentView.adjust({ width: 4000, height: 4000 });
|
263
|
+
});
|
264
|
+
|
265
|
+
// Scenario: right & bottom aligned, at maximums, content view grows: hug the right & bottom sides.
|
266
|
+
SC.run(function () {
|
267
|
+
view.scrollBy(3900, 3900);
|
268
|
+
contentView.adjust({ width: 4100, height: 4100 });
|
269
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset'), "After resizing the content with adjust width of 4100, horizontal offset must be at maximum");
|
270
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset'), "After resizing the content with adjust height of 4100 vertical offset must be at maximum");
|
271
|
+
});
|
272
|
+
|
273
|
+
// Reset the view.
|
274
|
+
SC.run(function () {
|
275
|
+
view.scrollTo(0, 0);
|
276
|
+
contentView.adjust({ width: 4000, height: 4000 });
|
277
|
+
});
|
278
|
+
|
279
|
+
// Set alignments to be center and middle.
|
280
|
+
SC.run(function() {
|
281
|
+
view.set('horizontalAlign', SC.ALIGN_CENTER);
|
282
|
+
view.set('verticalAlign', SC.ALIGN_MIDDLE);
|
283
|
+
});
|
284
|
+
|
285
|
+
// Scenario: center & middle aligned, at center & middle, content view shrinks: stick to center & middle
|
286
|
+
SC.run(function () {
|
287
|
+
view.scrollBy(1950, 1950);
|
288
|
+
contentView.adjust({ width: 3900, height: 3900 });
|
289
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset') / 2, "After resizing the content with adjust width of 3900, horizontal offset should stay centered");
|
290
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset') / 2, "After resizing the content with adjust height of 3900 vertical offset should stay centered");
|
291
|
+
});
|
292
|
+
|
293
|
+
// Reset the view.
|
294
|
+
SC.run(function () {
|
295
|
+
view.scrollTo(0, 0);
|
296
|
+
contentView.adjust({ width: 4000, height: 4000 });
|
297
|
+
});
|
298
|
+
|
299
|
+
// Scenario: center & middle aligned, at center & middle, scroll view grows: stick to center & middle
|
300
|
+
SC.run(function () {
|
301
|
+
view.scrollBy(1950, 1950);
|
302
|
+
contentView.adjust({ width: 4100, height: 4100 });
|
303
|
+
equals(view.get('horizontalScrollOffset'), view.get('maximumHorizontalScrollOffset') / 2, "After resizing the content with adjust width of 4100, horizontal offset should stay centered");
|
304
|
+
equals(view.get('verticalScrollOffset'), view.get('maximumVerticalScrollOffset') / 2, "After resizing the content with adjust height of 4100 vertical offset should stay centered");
|
305
|
+
});
|
306
|
+
});
|
307
|
+
|
120
308
|
test("Scrolling relative to the current possition of the container view", function () {
|
121
309
|
equals(view.get('horizontalScrollOffset'), 0, "Initial horizontal offset must be zero");
|
122
310
|
equals(view.get('verticalScrollOffset'), 0, "Initial vertical offset must be zero");
|
@@ -156,22 +344,26 @@ test("Scrolling to a rectangle", function () {
|
|
156
344
|
});
|
157
345
|
|
158
346
|
test("Scrolling to a view", function() {
|
159
|
-
var pane
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
layout: { height:
|
166
|
-
|
167
|
-
|
168
|
-
layout: { height:
|
169
|
-
|
170
|
-
|
171
|
-
|
347
|
+
var pane;
|
348
|
+
|
349
|
+
SC.run(function () {
|
350
|
+
pane = SC.MainPane.create({
|
351
|
+
childViews: ['scrollView'],
|
352
|
+
scrollView: SC.ScrollView.create({
|
353
|
+
layout: { height: 100, width: 100 },
|
354
|
+
canScale: YES,
|
355
|
+
contentView: SC.View.create({
|
356
|
+
layout: { height: 500, width: 500 },
|
357
|
+
childViews: ['innerView1', 'innerView2'],
|
358
|
+
innerView1: SC.View.create({
|
359
|
+
layout: { height: 100, width: 100, top: 150, left: 150 }
|
360
|
+
}),
|
361
|
+
innerView2: SC.View.create({
|
362
|
+
layout: { height: 100, width: 100, top: 200, left: 200 }
|
363
|
+
})
|
172
364
|
})
|
173
365
|
})
|
174
|
-
})
|
366
|
+
});
|
175
367
|
});
|
176
368
|
|
177
369
|
var scrollView = pane.scrollView,
|
@@ -286,7 +478,7 @@ test("maximumVerticalScrollOffset() returns the maximum vertical scroll dimensio
|
|
286
478
|
|
287
479
|
// ------------------------------------
|
288
480
|
// mouseWheel events
|
289
|
-
|
481
|
+
|
290
482
|
|
291
483
|
test("Mouse wheel events should only be captured if the scroll can scroll in the direction (both TOP-LEFT).", function () {
|
292
484
|
// FIRST GROUP: everything scrolled all the way to the top left
|
@@ -344,18 +536,13 @@ test("Mouse wheel events not capturable by the inner scroll should bubble to the
|
|
344
536
|
view4.scrollTo(114, 114);
|
345
537
|
});
|
346
538
|
|
347
|
-
window.stop();
|
348
|
-
|
349
539
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: 10, wheelDeltaY: 0 });
|
350
540
|
SC.Event.trigger(elem, 'mousewheel', event);
|
351
541
|
|
352
|
-
SC.
|
353
|
-
SC.Timer.schedule({ target: this, action: function () {
|
542
|
+
SC.run(function () {
|
354
543
|
equals(view4.get('horizontalScrollOffset'), 114, 'The inner scroll view should still have horizontalScrollOffset');
|
355
544
|
equals(view3.get('horizontalScrollOffset'), 10, 'The outer scroll view should now have horizontalScrollOffset');
|
356
|
-
|
357
|
-
}, interval: 200});
|
358
|
-
SC.RunLoop.end();
|
545
|
+
});
|
359
546
|
});
|
360
547
|
|
361
548
|
test("Mouse wheel events not capturable by the inner scroll should bubble to the outer scroll (scroll down).", function () {
|
@@ -367,18 +554,13 @@ test("Mouse wheel events not capturable by the inner scroll should bubble to the
|
|
367
554
|
view4.scrollTo(114, 114);
|
368
555
|
});
|
369
556
|
|
370
|
-
window.stop();
|
371
|
-
|
372
557
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: 0, wheelDeltaY: 10 });
|
373
558
|
SC.Event.trigger(elem, 'mousewheel', event);
|
374
559
|
|
375
|
-
SC.
|
376
|
-
SC.Timer.schedule({ target: this, action: function () {
|
560
|
+
SC.run(function () {
|
377
561
|
equals(view4.get('verticalScrollOffset'), 114, 'The inner scroll view should still have verticalScrollOffset');
|
378
562
|
equals(view3.get('verticalScrollOffset'), 10, 'The outer scroll view should now have verticalScrollOffset');
|
379
|
-
|
380
|
-
}, interval: 200});
|
381
|
-
SC.RunLoop.end();
|
563
|
+
});
|
382
564
|
});
|
383
565
|
|
384
566
|
test("Mouse wheel events not capturable by the inner scroll should bubble to the outer scroll (scroll left).", function () {
|
@@ -388,19 +570,16 @@ test("Mouse wheel events not capturable by the inner scroll should bubble to the
|
|
388
570
|
SC.run(function () {
|
389
571
|
view3.scrollTo(114, 114);
|
390
572
|
view4.scrollTo(0, 0);
|
391
|
-
|
392
|
-
SC.Timer.schedule({ target: this, action: function () {
|
393
|
-
equals(view4.get('horizontalScrollOffset'), 0, 'The inner scroll view should still have horizontalScrollOffset');
|
394
|
-
equals(view3.get('horizontalScrollOffset'), 104, 'The outer scroll view should now have horizontalScrollOffset');
|
395
|
-
window.start();
|
396
|
-
}, interval: 200});
|
397
573
|
});
|
398
574
|
|
399
|
-
window.stop();
|
400
|
-
|
401
575
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: -10, wheelDeltaY: 0 });
|
402
576
|
SC.Event.trigger(elem, 'mousewheel', event);
|
403
577
|
|
578
|
+
SC.run(function () {
|
579
|
+
equals(view4.get('horizontalScrollOffset'), 0, 'The inner scroll view should still have horizontalScrollOffset');
|
580
|
+
equals(view3.get('horizontalScrollOffset'), 104, 'The outer scroll view should now have horizontalScrollOffset');
|
581
|
+
|
582
|
+
});
|
404
583
|
});
|
405
584
|
|
406
585
|
test("Mouse wheel events not capturable by the inner scroll should bubble to the outer scroll (scroll up).", function () {
|
@@ -412,18 +591,13 @@ test("Mouse wheel events not capturable by the inner scroll should bubble to the
|
|
412
591
|
view4.scrollTo(0, 0);
|
413
592
|
});
|
414
593
|
|
415
|
-
window.stop();
|
416
|
-
|
417
594
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: 0, wheelDeltaY: -10 });
|
418
595
|
SC.Event.trigger(elem, 'mousewheel', event);
|
419
596
|
|
420
|
-
SC.
|
421
|
-
SC.Timer.schedule({ target: this, action: function () {
|
597
|
+
SC.run(function () {
|
422
598
|
equals(view4.get('verticalScrollOffset'), 0, 'The inner scroll view should still have verticalScrollOffset');
|
423
599
|
equals(view3.get('verticalScrollOffset'), 104, 'The outer scroll view should now have verticalScrollOffset');
|
424
|
-
|
425
|
-
}, interval: 200 });
|
426
|
-
SC.RunLoop.end();
|
600
|
+
});
|
427
601
|
});
|
428
602
|
|
429
603
|
test("Mouse wheel events capturable by the inner scroll should not bubble to the outer scroll (scroll right).", function () {
|
@@ -435,18 +609,13 @@ test("Mouse wheel events capturable by the inner scroll should not bubble to the
|
|
435
609
|
view4.scrollTo(0, 0);
|
436
610
|
});
|
437
611
|
|
438
|
-
window.stop();
|
439
|
-
|
440
612
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: 10, wheelDeltaY: 0 });
|
441
613
|
SC.Event.trigger(elem, 'mousewheel', event);
|
442
614
|
|
443
|
-
SC.
|
444
|
-
SC.Timer.schedule({ target: this, action: function () {
|
615
|
+
SC.run(function () {
|
445
616
|
equals(view4.get('horizontalScrollOffset'), 10, 'The inner scroll view should now have horizontalScrollOffset');
|
446
617
|
equals(view3.get('horizontalScrollOffset'), 0, 'The outer scroll view should still have horizontalScrollOffset');
|
447
|
-
|
448
|
-
}, interval: 200 });
|
449
|
-
SC.RunLoop.end();
|
618
|
+
});
|
450
619
|
});
|
451
620
|
|
452
621
|
test("Mouse wheel events capturable by the inner scroll should not bubble to the outer scroll (scroll up).", function () {
|
@@ -458,18 +627,13 @@ test("Mouse wheel events capturable by the inner scroll should not bubble to the
|
|
458
627
|
view4.scrollTo(114, 114);
|
459
628
|
});
|
460
629
|
|
461
|
-
window.stop();
|
462
|
-
|
463
630
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: 0, wheelDeltaY: -10 });
|
464
631
|
SC.Event.trigger(elem, 'mousewheel', event);
|
465
632
|
|
466
|
-
SC.
|
467
|
-
SC.Timer.schedule({ target: this, action: function () {
|
633
|
+
SC.run(function () {
|
468
634
|
equals(view4.get('verticalScrollOffset'), 104, 'The inner scroll view should now have verticalScrollOffset');
|
469
635
|
equals(view3.get('verticalScrollOffset'), 114, 'The outer scroll view should still have verticalScrollOffset');
|
470
|
-
|
471
|
-
}, interval: 200 });
|
472
|
-
SC.RunLoop.end();
|
636
|
+
});
|
473
637
|
});
|
474
638
|
|
475
639
|
test("Mouse wheel events capturable by the inner scroll should not bubble to the outer scroll (scroll left).", function () {
|
@@ -481,18 +645,13 @@ test("Mouse wheel events capturable by the inner scroll should not bubble to the
|
|
481
645
|
view4.scrollTo(114, 114);
|
482
646
|
});
|
483
647
|
|
484
|
-
window.stop();
|
485
|
-
|
486
648
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: -10, wheelDeltaY: 0 });
|
487
649
|
SC.Event.trigger(elem, 'mousewheel', event);
|
488
650
|
|
489
|
-
SC.
|
490
|
-
SC.Timer.schedule({ target: this, action: function () {
|
651
|
+
SC.run(function () {
|
491
652
|
equals(view4.get('horizontalScrollOffset'), 104, 'The inner scroll view should now have horizontalScrollOffset');
|
492
653
|
equals(view3.get('horizontalScrollOffset'), 114, 'The outer scroll view should still have horizontalScrollOffset');
|
493
|
-
|
494
|
-
}, interval: 200 });
|
495
|
-
SC.RunLoop.end();
|
654
|
+
});
|
496
655
|
});
|
497
656
|
|
498
657
|
test("Mouse wheel events capturable by the inner scroll should not bubble to the outer scroll (scroll down).", function () {
|
@@ -504,18 +663,15 @@ test("Mouse wheel events capturable by the inner scroll should not bubble to the
|
|
504
663
|
view4.scrollTo(0, 0);
|
505
664
|
});
|
506
665
|
|
507
|
-
window.stop();
|
666
|
+
// window.stop();
|
508
667
|
|
509
668
|
event = SC.Event.simulateEvent(elem, 'mousewheel', { wheelDeltaX: 0, wheelDeltaY: 10 });
|
510
669
|
SC.Event.trigger(elem, 'mousewheel', event);
|
511
670
|
|
512
|
-
SC.
|
513
|
-
SC.Timer.schedule({ target: this, action: function () {
|
671
|
+
SC.run(function () {
|
514
672
|
equals(view4.get('verticalScrollOffset'), 10, 'The inner scroll view should now have verticalScrollOffset');
|
515
673
|
equals(view3.get('verticalScrollOffset'), 0, 'The outer scroll view should still have verticalScrollOffset');
|
516
|
-
|
517
|
-
}, interval: 200 });
|
518
|
-
SC.RunLoop.end();
|
674
|
+
});
|
519
675
|
});
|
520
676
|
|
521
677
|
// ------------------------------------
|