sproutcore 1.11.0.rc1 → 1.11.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
// ------------------------------------
|