Commit 9bca8ac9 authored by daniela.mateescu's avatar daniela.mateescu Committed by Valentin Hervieu

fix: Fix for wrong slider drag when having many touches simultaneous

#534
parent 5bf3f228
This diff is collapsed.
/*! angularjs-slider - v6.1.2 - /*! angularjs-slider - v6.1.2 -
(c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com> - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com> -
https://github.com/angular-slider/angularjs-slider - https://github.com/angular-slider/angularjs-slider -
2017-05-15 */ 2017-05-25 */
/*jslint unparam: true */ /*jslint unparam: true */
/*global angular: false, console: false, define, module */ /*global angular: false, console: false, define, module */
(function(root, factory) { (function(root, factory) {
...@@ -158,7 +158,7 @@ ...@@ -158,7 +158,7 @@
.factory('RzSlider', ['$timeout', '$document', '$window', '$compile', 'RzSliderOptions', 'rzThrottle', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) { .factory('RzSlider', ['$timeout', '$document', '$window', '$compile', 'RzSliderOptions', 'rzThrottle', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) {
'use strict'; 'use strict';
/** /**
* Slider * Slider
* *
...@@ -458,7 +458,7 @@ ...@@ -458,7 +458,7 @@
} }
return index; return index;
}, },
syncLowValue: function() { syncLowValue: function() {
if (this.options.stepsArray) { if (this.options.stepsArray) {
if (!this.options.bindIndexForStepsArray) if (!this.options.bindIndexForStepsArray)
...@@ -1560,32 +1560,46 @@ ...@@ -1560,32 +1560,46 @@
* Get the X-coordinate or Y-coordinate of an event * Get the X-coordinate or Y-coordinate of an event
* *
* @param {Object} event The event * @param {Object} event The event
* @param targetTouchId The identifier of the touch for that we will get the x and y coordinates
* @returns {number} * @returns {number}
*/ */
getEventXY: function(event) { getEventXY: function(event, targetTouchId) {
/* http://stackoverflow.com/a/12336075/282882 */ /* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint //noinspection JSLint
var clientXY = this.options.vertical ? 'clientY' : 'clientX'; var clientXY = this.options.vertical ? 'clientY' : 'clientX';
if (event[clientXY] !== undefined) { if (event[clientXY] !== undefined) {
return event[clientXY]; return event[clientXY];
} }
return event.originalEvent === undefined ? var eventXY;
event.touches[0][clientXY] : event.originalEvent.touches[0][clientXY]; var touches = event.originalEvent === undefined ? event.touches : event.originalEvent.touches;
if (targetTouchId !== undefined) {
for (var i = 0; i < touches.length; i++) {
if (touches[i].identifier == targetTouchId) {
return touches[i][clientXY];
}
}
}
// If the target touch was not found in the event
// returns the coordinates of the first touch
return touches[0][clientXY];
}, },
/** /**
* Compute the event position depending on whether the slider is horizontal or vertical * Compute the event position depending on whether the slider is horizontal or vertical
* @param event * @param event
* @param targetTouchId If targetTouchId is provided it will be considered the position of that
* @returns {number} * @returns {number}
*/ */
getEventPosition: function(event) { getEventPosition: function(event, targetTouchId) {
var sliderPos = this.sliderElem.rzsp, var sliderPos = this.sliderElem.rzsp,
eventPos = 0; eventPos = 0;
if (this.options.vertical) if (this.options.vertical)
eventPos = -this.getEventXY(event) + sliderPos; eventPos = -this.getEventXY(event, targetTouchId) + sliderPos;
else else
eventPos = this.getEventXY(event) - sliderPos; eventPos = this.getEventXY(event, targetTouchId) - sliderPos;
return eventPos * this.options.scale - this.handleHalfDim; // #346 handleHalfDim is already scaled return eventPos * this.options.scale - this.handleHalfDim; // #346 handleHalfDim is already scaled
}, },
...@@ -1763,8 +1777,19 @@ ...@@ -1763,8 +1777,19 @@
ehEnd = angular.bind(this, this.onEnd, ehMove); ehEnd = angular.bind(this, this.onEnd, ehMove);
$document.on(eventNames.moveEvent, ehMove); $document.on(eventNames.moveEvent, ehMove);
$document.one(eventNames.endEvent, ehEnd);
$document.on(eventNames.endEvent, ehEnd);
this.ehEndToBeRemovedOnEnd = ehEnd;
this.callOnStart(); this.callOnStart();
var changedTouches = event.originalEvent === undefined ? event.changedTouches : event.originalEvent.changedTouches;
if (changedTouches) {
// Store the touch identifier
if (!this.touchId) {
this.isDragging = true;
this.touchId = changedTouches[0].identifier;
}
}
}, },
/** /**
...@@ -1776,7 +1801,22 @@ ...@@ -1776,7 +1801,22 @@
* @returns {undefined} * @returns {undefined}
*/ */
onMove: function(pointer, event, fromTick) { onMove: function(pointer, event, fromTick) {
var newPos = this.getEventPosition(event), var changedTouches = event.originalEvent === undefined ? event.changedTouches : event.originalEvent.changedTouches;
var touchForThisSlider;
if (changedTouches) {
for (var i = 0; i < changedTouches.length; i++) {
if (changedTouches[i].identifier == this.touchId) {
touchForThisSlider = changedTouches[i];
break;
}
}
}
if (changedTouches && !touchForThisSlider) {
return;
}
var newPos = this.getEventPosition(event, touchForThisSlider ? touchForThisSlider.identifier : undefined),
newValue, newValue,
ceilValue = this.options.rightToLeft ? this.minValue : this.maxValue, ceilValue = this.options.rightToLeft ? this.minValue : this.maxValue,
flrValue = this.options.rightToLeft ? this.maxValue : this.minValue; flrValue = this.options.rightToLeft ? this.maxValue : this.minValue;
...@@ -1794,7 +1834,7 @@ ...@@ -1794,7 +1834,7 @@
} }
this.positionTrackingHandle(newValue); this.positionTrackingHandle(newValue);
}, },
/** /**
* onEnd event handler * onEnd event handler
* *
...@@ -1803,6 +1843,16 @@ ...@@ -1803,6 +1843,16 @@
* @returns {undefined} * @returns {undefined}
*/ */
onEnd: function(ehMove, event) { onEnd: function(ehMove, event) {
var changedTouches = event.originalEvent === undefined ? event.changedTouches : event.originalEvent.changedTouches;
if (changedTouches && changedTouches[0].identifier != this.touchId) {
return;
}
this.isDragging = false;
this.touchId = null;
// Touch event, the listener was added by us so we need to remove it
$document.off("touchend", this.ehEndToBeRemovedOnEnd);
var moveEventName = this.getEventNames(event).moveEvent; var moveEventName = this.getEventNames(event).moveEvent;
if (!this.options.keyboardSupport) { if (!this.options.keyboardSupport) {
...@@ -1842,9 +1892,11 @@ ...@@ -1842,9 +1892,11 @@
onPointerBlur: function(pointer) { onPointerBlur: function(pointer) {
pointer.off('keydown'); pointer.off('keydown');
pointer.off('keyup'); pointer.off('keyup');
this.tracking = '';
pointer.removeClass('rz-active'); pointer.removeClass('rz-active');
this.currentFocusElement = null if (!this.isDragging) {
this.tracking = '';
this.currentFocusElement = null
}
}, },
/** /**
......
/*! angularjs-slider - v6.1.2 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com> - https://github.com/angular-slider/angularjs-slider - 2017-05-15 */ /*! angularjs-slider - v6.1.2 - (c) Rafal Zajac <rzajac@gmail.com>, Valentin Hervieu <valentin@hervieu.me>, Jussi Saarivirta <jusasi@gmail.com>, Angelin Sirbu <angelin.sirbu@gmail.com> - https://github.com/angular-slider/angularjs-slider - 2017-05-25 */
.rzslider{position:relative;display:inline-block;width:100%;height:4px;margin:35px 0 15px 0;vertical-align:middle;user-select:none}.rzslider.with-legend{margin-bottom:40px}.rzslider[disabled]{cursor:not-allowed}.rzslider[disabled] .rz-pointer{cursor:not-allowed;background-color:#d8e0f3}.rzslider[disabled] .rz-draggable{cursor:not-allowed}.rzslider[disabled] .rz-selection{background:#8b91a2}.rzslider[disabled] .rz-tick{cursor:not-allowed}.rzslider[disabled] .rz-tick.rz-selected{background:#8b91a2}.rzslider span{position:absolute;display:inline-block;white-space:nowrap}.rzslider .rz-base{width:100%;height:100%;padding:0}.rzslider .rz-bar-wrapper{left:0;z-index:1;width:100%;height:32px;padding-top:16px;margin-top:-16px;box-sizing:border-box}.rzslider .rz-draggable{cursor:move}.rzslider .rz-bar{left:0;z-index:1;width:100%;height:4px;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-pointer{top:-14px;z-index:3;width:32px;height:32px;cursor:pointer;background-color:#0db9f0;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px}.rzslider .rz-pointer:after{position:absolute;top:12px;left:12px;width:8px;height:8px;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;content:''}.rzslider .rz-pointer:hover:after{background-color:#fff}.rzslider .rz-pointer.rz-active{z-index:4}.rzslider .rz-pointer.rz-active:after{background-color:#451aff}.rzslider .rz-bubble{bottom:16px;padding:1px 3px;color:#55637d;cursor:default}.rzslider .rz-bubble.rz-limit{color:#55637d}.rzslider .rz-ticks{position:absolute;top:-3px;left:0;z-index:1;width:100%;height:0;margin:0;list-style:none;box-sizing:border-box}.rzslider .rz-ticks-values-under .rz-tick-value{top:auto;bottom:-32px}.rzslider .rz-tick{position:absolute;top:0;left:0;width:10px;height:10px;margin-left:11px;text-align:center;cursor:pointer;background:#d8e0f3;border-radius:50%}.rzslider .rz-tick.rz-selected{background:#0db9f0}.rzslider .rz-tick-value{position:absolute;top:-30px;transform:translate(-50%,0)}.rzslider .rz-tick-legend{position:absolute;top:24px;max-width:50px;white-space:normal;transform:translate(-50%,0)}.rzslider.rz-vertical{position:relative;width:4px;height:100%;padding:0;margin:0 20px;vertical-align:baseline}.rzslider.rz-vertical .rz-base{width:100%;height:100%;padding:0}.rzslider.rz-vertical .rz-bar-wrapper{top:auto;left:0;width:32px;height:100%;padding:0 0 0 16px;margin:0 0 0 -16px}.rzslider.rz-vertical .rz-bar{bottom:0;left:auto;width:4px;height:100%}.rzslider.rz-vertical .rz-pointer{top:auto;bottom:0;left:-14px!important}.rzslider.rz-vertical .rz-bubble{bottom:0;left:16px!important;margin-left:3px}.rzslider.rz-vertical .rz-ticks{top:0;left:-3px;z-index:1;width:0;height:100%}.rzslider.rz-vertical .rz-tick{margin-top:11px;margin-left:auto;vertical-align:middle}.rzslider.rz-vertical .rz-tick-value{top:auto;left:24px;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-tick-legend{top:auto;right:24px;max-width:none;white-space:nowrap;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-ticks-values-under .rz-tick-value{right:24px;bottom:auto;left:auto} .rzslider{position:relative;display:inline-block;width:100%;height:4px;margin:35px 0 15px 0;vertical-align:middle;user-select:none}.rzslider.with-legend{margin-bottom:40px}.rzslider[disabled]{cursor:not-allowed}.rzslider[disabled] .rz-pointer{cursor:not-allowed;background-color:#d8e0f3}.rzslider[disabled] .rz-draggable{cursor:not-allowed}.rzslider[disabled] .rz-selection{background:#8b91a2}.rzslider[disabled] .rz-tick{cursor:not-allowed}.rzslider[disabled] .rz-tick.rz-selected{background:#8b91a2}.rzslider span{position:absolute;display:inline-block;white-space:nowrap}.rzslider .rz-base{width:100%;height:100%;padding:0}.rzslider .rz-bar-wrapper{left:0;z-index:1;width:100%;height:32px;padding-top:16px;margin-top:-16px;box-sizing:border-box}.rzslider .rz-draggable{cursor:move}.rzslider .rz-bar{left:0;z-index:1;width:100%;height:4px;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-pointer{top:-14px;z-index:3;width:32px;height:32px;cursor:pointer;background-color:#0db9f0;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px}.rzslider .rz-pointer:after{position:absolute;top:12px;left:12px;width:8px;height:8px;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;content:''}.rzslider .rz-pointer:hover:after{background-color:#fff}.rzslider .rz-pointer.rz-active{z-index:4}.rzslider .rz-pointer.rz-active:after{background-color:#451aff}.rzslider .rz-bubble{bottom:16px;padding:1px 3px;color:#55637d;cursor:default}.rzslider .rz-bubble.rz-limit{color:#55637d}.rzslider .rz-ticks{position:absolute;top:-3px;left:0;z-index:1;width:100%;height:0;margin:0;list-style:none;box-sizing:border-box}.rzslider .rz-ticks-values-under .rz-tick-value{top:auto;bottom:-32px}.rzslider .rz-tick{position:absolute;top:0;left:0;width:10px;height:10px;margin-left:11px;text-align:center;cursor:pointer;background:#d8e0f3;border-radius:50%}.rzslider .rz-tick.rz-selected{background:#0db9f0}.rzslider .rz-tick-value{position:absolute;top:-30px;transform:translate(-50%,0)}.rzslider .rz-tick-legend{position:absolute;top:24px;max-width:50px;white-space:normal;transform:translate(-50%,0)}.rzslider.rz-vertical{position:relative;width:4px;height:100%;padding:0;margin:0 20px;vertical-align:baseline}.rzslider.rz-vertical .rz-base{width:100%;height:100%;padding:0}.rzslider.rz-vertical .rz-bar-wrapper{top:auto;left:0;width:32px;height:100%;padding:0 0 0 16px;margin:0 0 0 -16px}.rzslider.rz-vertical .rz-bar{bottom:0;left:auto;width:4px;height:100%}.rzslider.rz-vertical .rz-pointer{top:auto;bottom:0;left:-14px!important}.rzslider.rz-vertical .rz-bubble{bottom:0;left:16px!important;margin-left:3px}.rzslider.rz-vertical .rz-ticks{top:0;left:-3px;z-index:1;width:0;height:100%}.rzslider.rz-vertical .rz-tick{margin-top:11px;margin-left:auto;vertical-align:middle}.rzslider.rz-vertical .rz-tick-value{top:auto;left:24px;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-tick-legend{top:auto;right:24px;max-width:none;white-space:nowrap;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-ticks-values-under .rz-tick-value{right:24px;bottom:auto;left:auto}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
...@@ -162,7 +162,7 @@ ...@@ -162,7 +162,7 @@
.factory('RzSlider', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) { .factory('RzSlider', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) {
'use strict'; 'use strict';
/** /**
* Slider * Slider
* *
...@@ -462,7 +462,7 @@ ...@@ -462,7 +462,7 @@
} }
return index; return index;
}, },
syncLowValue: function() { syncLowValue: function() {
if (this.options.stepsArray) { if (this.options.stepsArray) {
if (!this.options.bindIndexForStepsArray) if (!this.options.bindIndexForStepsArray)
...@@ -1564,32 +1564,46 @@ ...@@ -1564,32 +1564,46 @@
* Get the X-coordinate or Y-coordinate of an event * Get the X-coordinate or Y-coordinate of an event
* *
* @param {Object} event The event * @param {Object} event The event
* @param targetTouchId The identifier of the touch with the X/Y coordinates
* @returns {number} * @returns {number}
*/ */
getEventXY: function(event) { getEventXY: function(event, targetTouchId) {
/* http://stackoverflow.com/a/12336075/282882 */ /* http://stackoverflow.com/a/12336075/282882 */
//noinspection JSLint //noinspection JSLint
var clientXY = this.options.vertical ? 'clientY' : 'clientX'; var clientXY = this.options.vertical ? 'clientY' : 'clientX';
if (event[clientXY] !== undefined) { if (event[clientXY] !== undefined) {
return event[clientXY]; return event[clientXY];
} }
return event.originalEvent === undefined ? var eventXY;
event.touches[0][clientXY] : event.originalEvent.touches[0][clientXY]; var touches = event.originalEvent === undefined ? event.touches : event.originalEvent.touches;
if (targetTouchId !== undefined) {
for (var i = 0; i < touches.length; i++) {
if (touches[i].identifier == targetTouchId) {
return touches[i][clientXY];
}
}
}
// If no target touch or the target touch was not found in the event
// returns the coordinates of the first touch
return touches[0][clientXY];
}, },
/** /**
* Compute the event position depending on whether the slider is horizontal or vertical * Compute the event position depending on whether the slider is horizontal or vertical
* @param event * @param event
* @param targetTouchId If targetTouchId is provided it will be considered the position of that
* @returns {number} * @returns {number}
*/ */
getEventPosition: function(event) { getEventPosition: function(event, targetTouchId) {
var sliderPos = this.sliderElem.rzsp, var sliderPos = this.sliderElem.rzsp,
eventPos = 0; eventPos = 0;
if (this.options.vertical) if (this.options.vertical)
eventPos = -this.getEventXY(event) + sliderPos; eventPos = -this.getEventXY(event, targetTouchId) + sliderPos;
else else
eventPos = this.getEventXY(event) - sliderPos; eventPos = this.getEventXY(event, targetTouchId) - sliderPos;
return eventPos * this.options.scale - this.handleHalfDim; // #346 handleHalfDim is already scaled return eventPos * this.options.scale - this.handleHalfDim; // #346 handleHalfDim is already scaled
}, },
...@@ -1767,8 +1781,19 @@ ...@@ -1767,8 +1781,19 @@
ehEnd = angular.bind(this, this.onEnd, ehMove); ehEnd = angular.bind(this, this.onEnd, ehMove);
$document.on(eventNames.moveEvent, ehMove); $document.on(eventNames.moveEvent, ehMove);
$document.one(eventNames.endEvent, ehEnd);
$document.on(eventNames.endEvent, ehEnd);
this.ehEndToBeRemovedOnEnd = ehEnd;
this.callOnStart(); this.callOnStart();
var changedTouches = event.originalEvent === undefined ? event.changedTouches : event.originalEvent.changedTouches;
if (changedTouches) {
// Store the touch identifier
if (!this.touchId) {
this.isDragging = true;
this.touchId = changedTouches[0].identifier;
}
}
}, },
/** /**
...@@ -1780,7 +1805,22 @@ ...@@ -1780,7 +1805,22 @@
* @returns {undefined} * @returns {undefined}
*/ */
onMove: function(pointer, event, fromTick) { onMove: function(pointer, event, fromTick) {
var newPos = this.getEventPosition(event), var changedTouches = event.originalEvent === undefined ? event.changedTouches : event.originalEvent.changedTouches;
var touchForThisSlider;
if (changedTouches) {
for (var i = 0; i < changedTouches.length; i++) {
if (changedTouches[i].identifier == this.touchId) {
touchForThisSlider = changedTouches[i];
break;
}
}
}
if (changedTouches && !touchForThisSlider) {
return;
}
var newPos = this.getEventPosition(event, touchForThisSlider ? touchForThisSlider.identifier : undefined),
newValue, newValue,
ceilValue = this.options.rightToLeft ? this.minValue : this.maxValue, ceilValue = this.options.rightToLeft ? this.minValue : this.maxValue,
flrValue = this.options.rightToLeft ? this.maxValue : this.minValue; flrValue = this.options.rightToLeft ? this.maxValue : this.minValue;
...@@ -1798,7 +1838,7 @@ ...@@ -1798,7 +1838,7 @@
} }
this.positionTrackingHandle(newValue); this.positionTrackingHandle(newValue);
}, },
/** /**
* onEnd event handler * onEnd event handler
* *
...@@ -1807,6 +1847,16 @@ ...@@ -1807,6 +1847,16 @@
* @returns {undefined} * @returns {undefined}
*/ */
onEnd: function(ehMove, event) { onEnd: function(ehMove, event) {
var changedTouches = event.originalEvent === undefined ? event.changedTouches : event.originalEvent.changedTouches;
if (changedTouches && changedTouches[0].identifier != this.touchId) {
return;
}
this.isDragging = false;
this.touchId = null;
// Touch event, the listener was added by us so we need to remove it
$document.off("touchend", this.ehEndToBeRemovedOnEnd);
var moveEventName = this.getEventNames(event).moveEvent; var moveEventName = this.getEventNames(event).moveEvent;
if (!this.options.keyboardSupport) { if (!this.options.keyboardSupport) {
...@@ -1846,9 +1896,11 @@ ...@@ -1846,9 +1896,11 @@
onPointerBlur: function(pointer) { onPointerBlur: function(pointer) {
pointer.off('keydown'); pointer.off('keydown');
pointer.off('keyup'); pointer.off('keyup');
this.tracking = '';
pointer.removeClass('rz-active'); pointer.removeClass('rz-active');
this.currentFocusElement = null if (!this.isDragging) {
this.tracking = '';
this.currentFocusElement = null
}
}, },
/** /**
......
...@@ -95,7 +95,74 @@ ...@@ -95,7 +95,74 @@
}; };
$document.triggerHandler(event); $document.triggerHandler(event);
}; };
h.fireTouchstartWithOriginalEvent = function(element, position, touchIdentifier, touchesIds, vertical) {
var event = {type:'touchstart', originalEvent: this.getTouchEvent('touchstart', position, vertical, touchIdentifier, touchesIds, sinon.stub())};
element.triggerHandler(event);
return event;
};
h.fireTouchstartWithoutOriginalEvent = function(element, position, touchIdentifier, touchesIds, vertical) {
var event = this.getTouchEvent('touchstart', position, vertical, touchIdentifier, touchesIds, sinon.stub());
element.triggerHandler(event);
return event;
};
h.fireTouchmoveWithOriginalEvent = function(position, touchIdentifier, touchesIds, vertical) {
var event = {type:'touchmove', originalEvent: this.getTouchEvent('touchmove', position, vertical, touchIdentifier, touchesIds)};
$document.triggerHandler(event);
return event;
};
h.fireTouchmoveWithoutOriginalEvent = function(position, touchIdentifier, touchesIds, vertical) {
var event = this.getTouchEvent('touchmove', position, vertical, touchIdentifier, touchesIds);
$document.triggerHandler(event);
return event;
};
h.fireTouchendWithOriginalEvent = function(touchIdentifier, touchesIds, vertical) {
var event = {type:'touchend', originalEvent: this.getTouchEvent('touchend', 0, vertical, touchIdentifier, touchesIds)};
$document.triggerHandler(event);
return event;
};
h.fireTouchendWithoutOriginalEvent = function(touchIdentifier, touchesIds, vertical) {
var event = this.getTouchEvent('touchend', 0, vertical, touchIdentifier, touchesIds);
$document.triggerHandler(event);
return event;
};
h.getTouchEvent = function(type, position, vertical, changedTouchId, touchesIds, preventDefaultAndStopPropagation) {
var positionProp = vertical ? 'clientY' : 'clientX';
var changedTouches = [{identifier:changedTouchId}];
changedTouches[0][positionProp] = position;
var touches = [];
for (var i = 0; i < touchesIds.length; i++) {
var touch = {identifier: touchesIds[i]};
if (touch.identifier == changedTouchId) {
touch[positionProp] = position;
}
touches.push(touch);
}
var originalEvent = {
type: type,
preventDefault: preventDefaultAndStopPropagation,
stopPropagation: preventDefaultAndStopPropagation,
changedTouches: changedTouches,
touches: touches
};
return originalEvent;
}
h.pressKeydown = function(element, key, options) { h.pressKeydown = function(element, key, options) {
options = options || {}; options = options || {};
key = key.toUpperCase(); key = key.toUpperCase();
...@@ -129,7 +196,7 @@ ...@@ -129,7 +196,7 @@
h.moveMouseToValue = function(value) { h.moveMouseToValue = function(value) {
h.fireMousemove(h.getMousePosition(value)); h.fireMousemove(h.getMousePosition(value));
}; };
return h; return h;
}); });
}()); }());
...@@ -407,5 +407,99 @@ ...@@ -407,5 +407,99 @@
expect(helper.slider.callOnStart.callCount).to.equal(1); expect(helper.slider.callOnStart.callCount).to.equal(1);
expect(helper.slider.callOnChange.callCount).to.equal(1); expect(helper.slider.callOnChange.callCount).to.equal(1);
}); });
it('should handle touch start, touch move and touch end correctly when multitouch with originalEvent', function() {
sinon.spy(helper.slider, 'positionTrackingHandle');
sinon.spy(helper.slider, 'callOnChange');
// Touch start for the slider
helper.fireTouchstartWithOriginalEvent(helper.slider.minH, 0, 0, [0]);
var expectedValue = 50;
var touchPositionForSlider = helper.getMousePosition(expectedValue);
// Touch move for the slider
helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1]);
// Simultaneous touch move but not on slider
var otherTouchPosition = touchPositionForSlider + 100;
helper.fireTouchmoveWithOriginalEvent(otherTouchPosition, 1, [0, 1]);
// The slider does not react
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(1);
expect(helper.slider.callOnChange.callCount).to.equal(1);
// The other simultaneous touch ends
helper.fireTouchendWithOriginalEvent(1, [0,1]);
var expectedValue = 60;
var touchPositionForSlider = helper.getMousePosition(expectedValue);
// Touch move for the slider
helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1]);
// Can still drag the slider
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
// Slider touch ends
helper.fireTouchendWithOriginalEvent(0, [0,1]);
// Touch move for the slider
var touchPositionForSlider = helper.getMousePosition(70);
helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1]);
// Can not drag the slider anymore
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
});
it('should handle touch start, touch move and touch end correctly when multitouch without originalEvent', function() {
sinon.spy(helper.slider, 'positionTrackingHandle');
sinon.spy(helper.slider, 'callOnChange');
// Touch start for the slider
var eventOnSlider = helper.fireTouchstartWithoutOriginalEvent(helper.slider.minH, 0, 0, [0]);
var expectedValue = 50;
var touchPositionForSlider = helper.getMousePosition(expectedValue);
// Touch move for the slider
helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [0, 1]);
// Simultaneous touch move but not on slider
var otherTouchPosition = touchPositionForSlider + 100;
helper.fireTouchmoveWithoutOriginalEvent(otherTouchPosition, 1, [0, 1]);
// The slider does not react
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(1);
expect(helper.slider.callOnChange.callCount).to.equal(1);
// The other simultaneous touch ends
helper.fireTouchendWithoutOriginalEvent(1, [0,1]);
var expectedValue = 60;
var touchPositionForSlider = helper.getMousePosition(expectedValue);
// Touch move for slider
helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [0, 1]);
// Can still drag the slider
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
// Slider touch ends
helper.fireTouchendWithoutOriginalEvent(0, [0,1]);
// Touch move for the slider
var touchPositionForSlider = helper.getMousePosition(70);
helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [0, 1]);
// Can not drag the slider anymore
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
});
}); });
}()); }());
...@@ -414,6 +414,101 @@ ...@@ -414,6 +414,101 @@
expect(helper.slider.callOnStart.callCount).to.equal(1); expect(helper.slider.callOnStart.callCount).to.equal(1);
expect(helper.slider.callOnChange.callCount).to.equal(1); expect(helper.slider.callOnChange.callCount).to.equal(1);
}); });
it('should handle touch start, touch move and touch end correctly when multitouch with originalEvent', function() {
sinon.spy(helper.slider, 'positionTrackingHandle');
sinon.spy(helper.slider, 'callOnChange');
// Touch start for the slider
var eventOnSlider = helper.fireTouchstartWithOriginalEvent(helper.slider.minH, 0, 0, [0], true);
var expectedValue = 50;
var touchPositionForSlider = helper.slider.sliderElem.rzsp - helper.slider.valueToPosition(expectedValue) - helper.slider.handleHalfDim;
// Touch move for the slider
helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1], true);
// Simultaneous touch move but not on slider
var otherTouchPosition = touchPositionForSlider + 100;
helper.fireTouchmoveWithOriginalEvent(otherTouchPosition, 1, [0, 1], true);
// The slider does not react
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(1);
expect(helper.slider.callOnChange.callCount).to.equal(1);
// The other simultaneous touch ends
helper.fireTouchendWithOriginalEvent(1, [0,1], true);
var expectedValue = 60;
var touchPositionForSlider = helper.slider.sliderElem.rzsp - helper.slider.valueToPosition(expectedValue) - helper.slider.handleHalfDim;
// Touch move for the slider
helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1], true);
// Can still drag the slider
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
// Slider touch ends
helper.fireTouchendWithOriginalEvent(0, [0,1], true);
// Touch move for the slider
var touchPositionForSlider = helper.slider.sliderElem.rzsp - helper.slider.valueToPosition(70) - helper.slider.handleHalfDim;
helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1], true);
//Can not drag the slider anymore
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
});
it('should handle touch start, touch move and touch end correctly when multitouch without originalEvent', function() {
sinon.spy(helper.slider, 'positionTrackingHandle');
sinon.spy(helper.slider, 'callOnChange');
// Touch start for the slider
var eventOnSlider = helper.fireTouchstartWithoutOriginalEvent(helper.slider.minH, 0, 0, [0], true);
var expectedValue = 50;
var touchPositionForSlider = helper.slider.sliderElem.rzsp - helper.slider.valueToPosition(expectedValue) - helper.slider.handleHalfDim;
// Touch move for slider
helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [0, 1], true);
// Simultaneous touch move but not on slider
var otherTouchPosition = touchPositionForSlider + 100;
helper.fireTouchmoveWithoutOriginalEvent(otherTouchPosition, 1, [0, 1], true);
// The slider does not react
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(1);
expect(helper.slider.callOnChange.callCount).to.equal(1);
// The other simultaneous touch ends
helper.fireTouchendWithoutOriginalEvent(1, [0,1], true);
var expectedValue = 60;
var touchPositionForSlider = helper.slider.sliderElem.rzsp - helper.slider.valueToPosition(expectedValue) - helper.slider.handleHalfDim;
// Touch move for slider
helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [0, 1], true);
// Can still drag the slider
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
// Slider touch ends
helper.fireTouchendWithoutOriginalEvent(0, [0,1], true);
// Touch move for the slider
var touchPositionForSlider = helper.slider.sliderElem.rzsp - helper.slider.valueToPosition(70) - helper.slider.handleHalfDim;
// Can not drag the slider anymore
helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [0, 1], true);
expect(helper.scope.slider.value).to.equal(expectedValue);
expect(helper.slider.positionTrackingHandle.callCount).to.equal(2);
expect(helper.slider.callOnChange.callCount).to.equal(2);
});
}); });
}()); }());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment