Merge branch 'master' into collections

This commit is contained in:
Ian Gilman 2014-12-31 15:17:43 -08:00
commit 48eaf7c805
2 changed files with 152 additions and 59 deletions

View File

@ -58,6 +58,7 @@ OPENSEADRAGON CHANGELOG
* Added option for home button to fill viewer (#474) * Added option for home button to fill viewer (#474)
* Better handling of mid-update image loaded callbacks (#409) * Better handling of mid-update image loaded callbacks (#409)
* Tracked pointers are now cleaned up when Viewer.setMouseNavEnabled(false) is called (#518) * Tracked pointers are now cleaned up when Viewer.setMouseNavEnabled(false) is called (#518)
* Added explicit pointer capture for touch event model touchstart events (#552)
1.1.1: 1.1.1:

View File

@ -170,8 +170,6 @@
* @private * @private
* @property {Boolean} tracking * @property {Boolean} tracking
* Are we currently tracking pointer events for this element. * Are we currently tracking pointer events for this element.
* @property {Boolean} capturing
* Are we curruently capturing mouse events (legacy mouse events only).
*/ */
THIS[ this.hash ] = { THIS[ this.hash ] = {
click: function ( event ) { onClick( _this, event ); }, click: function ( event ) { onClick( _this, event ); },
@ -197,7 +195,9 @@
touchleave: function ( event ) { onTouchLeave( _this, event ); }, touchleave: function ( event ) { onTouchLeave( _this, event ); },
touchstart: function ( event ) { onTouchStart( _this, event ); }, touchstart: function ( event ) { onTouchStart( _this, event ); },
touchend: function ( event ) { onTouchEnd( _this, event ); }, touchend: function ( event ) { onTouchEnd( _this, event ); },
touchendcaptured: function ( event ) { onTouchEndCaptured( _this, event ); },
touchmove: function ( event ) { onTouchMove( _this, event ); }, touchmove: function ( event ) { onTouchMove( _this, event ); },
touchmovecaptured: function ( event ) { onTouchMoveCaptured( _this, event ); },
touchcancel: function ( event ) { onTouchCancel( _this, event ); }, touchcancel: function ( event ) { onTouchCancel( _this, event ); },
gesturestart: function ( event ) { onGestureStart( _this, event ); }, gesturestart: function ( event ) { onGestureStart( _this, event ); },
@ -227,12 +227,6 @@
// of the element (for hover-capable devices) and/or have contact or a button press initiated in the element. // of the element (for hover-capable devices) and/or have contact or a button press initiated in the element.
activePointersLists: [], activePointersLists: [],
// Legacy mouse capture tracking
capturing: false,
// Pointer event model capture tracking
pointerCaptureCount: 0,
// Tracking for double-click gesture // Tracking for double-click gesture
lastClickPos: null, lastClickPos: null,
dblClickTimeOut: null, dblClickTimeOut: null,
@ -944,6 +938,12 @@
* @memberof OpenSeadragon.MouseTracker.GesturePointList# * @memberof OpenSeadragon.MouseTracker.GesturePointList#
*/ */
this.clicks = 0; this.clicks = 0;
/**
* Current number of captured pointers for the device.
* @member {Number} captureCount
* @memberof OpenSeadragon.MouseTracker.GesturePointList#
*/
this.captureCount = 0;
}; };
$.MouseTracker.GesturePointList.prototype = /** @lends OpenSeadragon.MouseTracker.GesturePointList.prototype */{ $.MouseTracker.GesturePointList.prototype = /** @lends OpenSeadragon.MouseTracker.GesturePointList.prototype */{
/** /**
@ -1042,33 +1042,47 @@
i, i,
pointerListCount = delegate.activePointersLists.length; pointerListCount = delegate.activePointersLists.length;
if ( delegate.pointerCaptureCount > 0 ) { for ( i = 0; i < pointerListCount; i++ ) {
$.removeEvent( if ( delegate.activePointersLists[ i ].captureCount > 0 ) {
$.MouseTracker.captureElement, $.removeEvent(
'mousemove', $.MouseTracker.captureElement,
delegate.mousemovecaptured, 'mousemove',
true delegate.mousemovecaptured,
); true
$.removeEvent( );
$.MouseTracker.captureElement, $.removeEvent(
'mouseup', $.MouseTracker.captureElement,
delegate.mouseupcaptured, 'mouseup',
true delegate.mouseupcaptured,
); true
$.removeEvent( );
$.MouseTracker.captureElement, $.removeEvent(
$.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', $.MouseTracker.captureElement,
delegate.pointermovecaptured, $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove',
true delegate.pointermovecaptured,
); true
$.removeEvent( );
$.MouseTracker.captureElement, $.removeEvent(
$.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', $.MouseTracker.captureElement,
delegate.pointerupcaptured, $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp',
true delegate.pointerupcaptured,
); true
);
$.removeEvent(
$.MouseTracker.captureElement,
'touchmove',
delegate.touchmovecaptured,
true
);
$.removeEvent(
$.MouseTracker.captureElement,
'touchend',
delegate.touchendcaptured,
true
);
delegate.pointerCaptureCount = 0; delegate.activePointersLists[ i ].captureCount = 0;
}
} }
for ( i = 0; i < pointerListCount; i++ ) { for ( i = 0; i < pointerListCount; i++ ) {
@ -1130,29 +1144,62 @@
} }
} }
/**
* @private
* @inner
*/
function getCaptureEventParams( tracker, pointerType ) {
var delegate = THIS[ tracker.hash ];
if ( pointerType === 'mouse' ) {
return {
upName: 'mouseup',
upHandler: delegate.mouseupcaptured,
moveName: 'mousemove',
moveHandler: delegate.mousemovecaptured
};
} else if ( pointerType === 'touch' ) {
return {
upName: 'touchend',
upHandler: delegate.touchendcaptured,
moveName: 'touchmove',
moveHandler: delegate.touchmovecaptured
};
} else {
return {
upName: $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp',
upHandler: delegate.pointerupcaptured,
moveName: $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove',
moveHandler: delegate.pointermovecaptured
};
}
}
/** /**
* Begin capturing pointer events to the tracked element. * Begin capturing pointer events to the tracked element.
* @private * @private
* @inner * @inner
*/ */
function capturePointer( tracker, isLegacyMouse ) { function capturePointer( tracker, pointerType ) {
var delegate = THIS[ tracker.hash ]; var delegate = THIS[ tracker.hash ],
pointsList = tracker.getActivePointersListByType( pointerType ),
eventParams = getCaptureEventParams( tracker, pointerType );
delegate.pointerCaptureCount++; pointsList.captureCount++;
if ( delegate.pointerCaptureCount === 1 ) { if ( pointsList.captureCount === 1 ) {
// We emulate mouse capture by hanging listeners on the window object. // We emulate mouse capture by hanging listeners on the window object.
// (Note we listen on the capture phase so the captured handlers will get called first) // (Note we listen on the capture phase so the captured handlers will get called first)
$.addEvent( $.addEvent(
$.MouseTracker.captureElement, $.MouseTracker.captureElement,
isLegacyMouse ? 'mouseup' : ($.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp'), eventParams.upName,
isLegacyMouse ? delegate.mouseupcaptured : delegate.pointerupcaptured, eventParams.upHandler,
true true
); );
$.addEvent( $.addEvent(
$.MouseTracker.captureElement, $.MouseTracker.captureElement,
isLegacyMouse ? 'mousemove' : ($.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove'), eventParams.moveName,
isLegacyMouse ? delegate.mousemovecaptured : delegate.pointermovecaptured, eventParams.moveHandler,
true true
); );
} }
@ -1164,24 +1211,26 @@
* @private * @private
* @inner * @inner
*/ */
function releasePointer( tracker, isLegacyMouse ) { function releasePointer( tracker, pointerType ) {
var delegate = THIS[ tracker.hash ]; var delegate = THIS[ tracker.hash ],
pointsList = tracker.getActivePointersListByType( pointerType ),
eventParams = getCaptureEventParams( tracker, pointerType );
delegate.pointerCaptureCount--; pointsList.captureCount--;
if ( delegate.pointerCaptureCount === 0 ) { if ( pointsList.captureCount === 0 ) {
// We emulate mouse capture by hanging listeners on the window object. // We emulate mouse capture by hanging listeners on the window object.
// (Note we listen on the capture phase so the captured handlers will get called first) // (Note we listen on the capture phase so the captured handlers will get called first)
$.removeEvent( $.removeEvent(
$.MouseTracker.captureElement, $.MouseTracker.captureElement,
isLegacyMouse ? 'mousemove' : ($.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove'), eventParams.moveName,
isLegacyMouse ? delegate.mousemovecaptured : delegate.pointermovecaptured, eventParams.moveHandler,
true true
); );
$.removeEvent( $.removeEvent(
$.MouseTracker.captureElement, $.MouseTracker.captureElement,
isLegacyMouse ? 'mouseup' : ($.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp'), eventParams.upName,
isLegacyMouse ? delegate.mouseupcaptured : delegate.pointerupcaptured, eventParams.upHandler,
true true
); );
} }
@ -1526,7 +1575,7 @@
if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) {
$.stopEvent( event ); $.stopEvent( event );
capturePointer( tracker, true ); capturePointer( tracker, 'mouse' );
} }
if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler ) { if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler ) {
@ -1574,7 +1623,7 @@
}; };
if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) {
releasePointer( tracker, true ); releasePointer( tracker, 'mouse' );
} }
} }
@ -1695,8 +1744,8 @@
} }
if ( updatePointersDown( tracker, event, gPoints, 0 ) ) { // 0 means primary button press/release or touch contact if ( updatePointersDown( tracker, event, gPoints, 0 ) ) { // 0 means primary button press/release or touch contact
// Touch event model start, end, and move events are always captured so we don't need to capture explicitly
$.stopEvent( event ); $.stopEvent( event );
capturePointer( tracker, 'touch' );
} }
$.cancelEvent( event ); $.cancelEvent( event );
@ -1708,6 +1757,28 @@
* @inner * @inner
*/ */
function onTouchEnd( tracker, event ) { function onTouchEnd( tracker, event ) {
handleTouchEnd( tracker, event );
}
/**
* This handler is attached to the window object (on the capture phase) to emulate pointer capture.
* onTouchEnd is still attached to the tracked element, so stop propagation to avoid processing twice.
*
* @private
* @inner
*/
function onTouchEndCaptured( tracker, event ) {
handleTouchEnd( tracker, event );
$.stopEvent( event );
}
/**
* @private
* @inner
*/
function handleTouchEnd( tracker, event ) {
var time, var time,
i, i,
touchCount = event.changedTouches.length, touchCount = event.changedTouches.length,
@ -1725,9 +1796,9 @@
} ); } );
} }
// Touch event model start, end, and move events are always captured so we don't need to release capture. if ( updatePointersUp( tracker, event, gPoints, 0 ) ) {
// We'll ignore the should-release-capture return value here releasePointer( tracker, 'touch' );
updatePointersUp( tracker, event, gPoints, 0 ); // 0 means primary button press/release or touch contact }
// simulate touchleave if not natively available // simulate touchleave if not natively available
if ( !$.MouseTracker.haveTouchEnter && touchCount > 0 ) { if ( !$.MouseTracker.haveTouchEnter && touchCount > 0 ) {
@ -1743,6 +1814,28 @@
* @inner * @inner
*/ */
function onTouchMove( tracker, event ) { function onTouchMove( tracker, event ) {
handleTouchMove( tracker, event );
}
/**
* This handler is attached to the window object (on the capture phase) to emulate pointer capture.
* onTouchMove is still attached to the tracked element, so stop propagation to avoid processing twice.
*
* @private
* @inner
*/
function onTouchMoveCaptured( tracker, event ) {
handleTouchMove( tracker, event );
$.stopEvent( event );
}
/**
* @private
* @inner
*/
function handleTouchMove( tracker, event ) {
var i, var i,
touchCount = event.changedTouches.length, touchCount = event.changedTouches.length,
gPoints = []; gPoints = [];
@ -1866,8 +1959,8 @@
}; };
if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) {
capturePointer( tracker, false );
$.stopEvent( event ); $.stopEvent( event );
capturePointer( tracker, 'pointer' );
} }
if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
@ -1917,8 +2010,7 @@
}; };
if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) {
releasePointer( tracker, false ); releasePointer( tracker, 'pointer' );
//$.stopEvent( event );
} }
} }