MouseTracker enhancements, improved IE <=10 support

This commit is contained in:
Mark Salsbery 2020-07-25 18:30:06 -07:00
parent d2bb480363
commit 2d4a723854
3 changed files with 79 additions and 66 deletions

View file

@ -17,6 +17,8 @@ OPENSEADRAGON CHANGELOG
* DEPRECATION: MouseTracker exitHandler deprecated for name change to leaveHandler for consistency with DOM event names * DEPRECATION: MouseTracker exitHandler deprecated for name change to leaveHandler for consistency with DOM event names
* Added missing Button event object properties (were listed in documentation but not implemented) * Added missing Button event object properties (were listed in documentation but not implemented)
* Fixed bug in Button class where two MouseTracker event handlers used an invalid "this" causing issues in some browsers * Fixed bug in Button class where two MouseTracker event handlers used an invalid "this" causing issues in some browsers
* MouseTracker: IE 10 - MSPointerEnter/MSPointerLeave didn't exist then, simulated with MSPointerOver/MSPointerOut
* MouseTracker: Simulate mouseover/mouseout on IE < 9
2.4.2: 2.4.2:

View file

@ -172,7 +172,7 @@
this.enterHandler = options.enterHandler || null; this.enterHandler = options.enterHandler || null;
this.leaveHandler = options.leaveHandler || null; this.leaveHandler = options.leaveHandler || null;
this.exitHandler = options.exitHandler || null; this.exitHandler = options.exitHandler || null; // Deprecated v2.4.3
this.overHandler = options.overHandler || null; this.overHandler = options.overHandler || null;
this.outHandler = options.outHandler || null; this.outHandler = options.outHandler || null;
this.pressHandler = options.pressHandler || null; this.pressHandler = options.pressHandler || null;
@ -216,10 +216,10 @@
DOMMouseScroll: function ( event ) { onMouseWheel( _this, event ); }, DOMMouseScroll: function ( event ) { onMouseWheel( _this, event ); },
MozMousePixelScroll: function ( event ) { onMouseWheel( _this, event ); }, MozMousePixelScroll: function ( event ) { onMouseWheel( _this, event ); },
mouseover: function ( event ) { onMouseOver( _this, event ); }, // IE9+ only
mouseout: function ( event ) { onMouseOut( _this, event ); }, // IE9+ only
mouseenter: function ( event ) { onMouseEnter( _this, event ); }, mouseenter: function ( event ) { onMouseEnter( _this, event ); },
mouseleave: function ( event ) { onMouseLeave( _this, event ); }, mouseleave: function ( event ) { onMouseLeave( _this, event ); },
mouseover: function ( event ) { onMouseOver( _this, event ); }, // IE9+ only
mouseout: function ( event ) { onMouseOut( _this, event ); }, // IE9+ only
mousedown: function ( event ) { onMouseDown( _this, event ); }, mousedown: function ( event ) { onMouseDown( _this, event ); },
mouseup: function ( event ) { onMouseUp( _this, event ); }, mouseup: function ( event ) { onMouseUp( _this, event ); },
mouseupcaptured: function ( event ) { onMouseUpCaptured( _this, event ); }, mouseupcaptured: function ( event ) { onMouseUpCaptured( _this, event ); },
@ -236,14 +236,12 @@
gesturestart: function ( event ) { onGestureStart( _this, event ); }, gesturestart: function ( event ) { onGestureStart( _this, event ); },
gesturechange: function ( event ) { onGestureChange( _this, event ); }, gesturechange: function ( event ) { onGestureChange( _this, event ); },
pointerenter: function ( event ) { onPointerEnter( _this, event ); },
pointerleave: function ( event ) { onPointerLeave( _this, event ); },
pointerover: function ( event ) { onPointerOver( _this, event ); }, pointerover: function ( event ) { onPointerOver( _this, event ); },
MSPointerOver: function ( event ) { onPointerOver( _this, event ); }, MSPointerOver: function ( event ) { onPointerOver( _this, event ); },
pointerout: function ( event ) { onPointerOut( _this, event ); }, pointerout: function ( event ) { onPointerOut( _this, event ); },
MSPointerOut: function ( event ) { onPointerOut( _this, event ); }, MSPointerOut: function ( event ) { onPointerOut( _this, event ); },
pointerenter: function ( event ) { onPointerEnter( _this, event ); },
MSPointerEnter: function ( event ) { onPointerEnter( _this, event ); },
pointerleave: function ( event ) { onPointerLeave( _this, event ); },
MSPointerLeave: function ( event ) { onPointerLeave( _this, event ); },
pointerdown: function ( event ) { onPointerDown( _this, event ); }, pointerdown: function ( event ) { onPointerDown( _this, event ); },
MSPointerDown: function ( event ) { onPointerDown( _this, event ); }, MSPointerDown: function ( event ) { onPointerDown( _this, event ); },
pointerup: function ( event ) { onPointerUp( _this, event ); }, pointerup: function ( event ) { onPointerUp( _this, event ); },
@ -425,7 +423,7 @@
* Implement or assign implementation to these handlers during or after * Implement or assign implementation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @deprecated Use leaveHandler instead * @since v2.4.3
* @param {Object} event * @param {Object} event
* @param {OpenSeadragon.MouseTracker} event.eventSource * @param {OpenSeadragon.MouseTracker} event.eventSource
* A reference to the tracker instance. * A reference to the tracker instance.
@ -456,7 +454,7 @@
* Implement or assign implementation to these handlers during or after * Implement or assign implementation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @deprecated Use leaveHandler instead * @deprecated v2.4.3 Use leaveHandler instead
* @param {Object} event * @param {Object} event
* @param {OpenSeadragon.MouseTracker} event.eventSource * @param {OpenSeadragon.MouseTracker} event.eventSource
* A reference to the tracker instance. * A reference to the tracker instance.
@ -489,6 +487,7 @@
* Implement or assign implementation to these handlers during or after * Implement or assign implementation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @since v2.4.3
* @param {Object} event * @param {Object} event
* @param {OpenSeadragon.MouseTracker} event.eventSource * @param {OpenSeadragon.MouseTracker} event.eventSource
* A reference to the tracker instance. * A reference to the tracker instance.
@ -521,6 +520,7 @@
* Implement or assign implementation to these handlers during or after * Implement or assign implementation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @since v2.4.3
* @param {Object} event * @param {Object} event
* @param {OpenSeadragon.MouseTracker} event.eventSource * @param {OpenSeadragon.MouseTracker} event.eventSource
* A reference to the tracker instance. * A reference to the tracker instance.
@ -1109,14 +1109,6 @@
document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least 'mousewheel' document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least 'mousewheel'
'DOMMouseScroll'; // Assume old Firefox 'DOMMouseScroll'; // Assume old Firefox
/**
* Detect legacy mouse capture support.
*/
$.MouseTracker.supportsMouseCapture = (function () {
var divElement = document.createElement( 'div' );
return $.isFunction( divElement.setCapture ) && $.isFunction( divElement.releaseCapture );
}());
/** /**
* Detect browser pointer device event model(s) and build appropriate list of events to subscribe to. * Detect browser pointer device event model(s) and build appropriate list of events to subscribe to.
*/ */
@ -1132,34 +1124,41 @@
$.MouseTracker.havePointerEvents = true; $.MouseTracker.havePointerEvents = true;
$.MouseTracker.subscribeEvents.push( "pointerenter", "pointerleave", "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" ); $.MouseTracker.subscribeEvents.push( "pointerenter", "pointerleave", "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" );
$.MouseTracker.unprefixedPointerEvents = true; $.MouseTracker.unprefixedPointerEvents = true;
if( navigator.maxTouchPoints ) { $.MouseTracker.havePointerOverOut = true;
$.MouseTracker.maxTouchPoints = navigator.maxTouchPoints; // Pointer events capture support
} else { $.MouseTracker.havePointerCapture = (function () {
$.MouseTracker.maxTouchPoints = 0; var divElement = document.createElement( 'div' );
} return $.isFunction( divElement.setPointerCapture ) && $.isFunction( divElement.releasePointerCapture );
$.MouseTracker.haveMouseOver = true; }());
} else if ( window.MSPointerEvent && window.navigator.msPointerEnabled ) { } else if ( window.MSPointerEvent && window.navigator.msPointerEnabled ) {
// IE10 // IE10 (MSPointerEnter/MSPointerLeave simulated with MSPointerOver/MSPointerOut)
$.MouseTracker.havePointerEvents = true; $.MouseTracker.havePointerEvents = true;
$.MouseTracker.subscribeEvents.push( "MSPointerEnter", "MSPointerLeave", "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" ); $.MouseTracker.subscribeEvents.push( "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" );
$.MouseTracker.unprefixedPointerEvents = false; $.MouseTracker.unprefixedPointerEvents = false;
if( navigator.msMaxTouchPoints ) { $.MouseTracker.havePointerOverOut = true;
$.MouseTracker.maxTouchPoints = navigator.msMaxTouchPoints; // Prefixed pointer events capture support
} else { $.MouseTracker.havePointerCapture = (function () {
$.MouseTracker.maxTouchPoints = 0; var divElement = document.createElement( 'div' );
} return $.isFunction( divElement.msSetPointerCapture ) && $.isFunction( divElement.msReleasePointerCapture );
$.MouseTracker.haveMouseOver = true; }());
} else { } else {
// Legacy W3C mouse events // Legacy W3C mouse events
$.MouseTracker.havePointerEvents = false; $.MouseTracker.havePointerEvents = false;
$.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" );
if ( $.Browser.vendor !== $.BROWSERS.IE || $.Browser.version > 8 ) { if ( $.Browser.vendor !== $.BROWSERS.IE || $.Browser.version > 8 ) {
$.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" );
$.MouseTracker.haveMouseOver = true; $.MouseTracker.havePointerOverOut = true;
} else { } else {
$.MouseTracker.haveMouseOver = false; $.MouseTracker.havePointerOverOut = false;
} }
$.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" );
$.MouseTracker.mousePointerId = "legacy-mouse";
// Legacy mouse events capture support
$.MouseTracker.havePointerCapture = (function () {
var divElement = document.createElement( 'div' );
return $.isFunction( divElement.setCapture ) && $.isFunction( divElement.releaseCapture );
}());
// Legacy touch events
if ( 'ontouchstart' in window ) { if ( 'ontouchstart' in window ) {
// iOS, Android, and other W3c Touch Event implementations // iOS, Android, and other W3c Touch Event implementations
// (see http://www.w3.org/TR/touch-events/) // (see http://www.w3.org/TR/touch-events/)
@ -1172,8 +1171,6 @@
// Subscribe to these to prevent default gesture handling // Subscribe to these to prevent default gesture handling
$.MouseTracker.subscribeEvents.push( "gesturestart", "gesturechange" ); $.MouseTracker.subscribeEvents.push( "gesturestart", "gesturechange" );
} }
$.MouseTracker.mousePointerId = "legacy-mouse";
$.MouseTracker.maxTouchPoints = 10;
} }
@ -1954,10 +1951,10 @@
updatePointersEnter( tracker, event, [ gPoint ] ); updatePointersEnter( tracker, event, [ gPoint ] );
//TODO simulate mouseover on IE < 9? // Simulate mouseover on IE < 9
// if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) { if ( !$.MouseTracker.havePointerOverOut ) {
// handleMouseOver( tracker, event ); handleMouseOver( tracker, event );
// } }
} }
@ -1978,10 +1975,10 @@
updatePointersLeave( tracker, event, [ gPoint ] ); updatePointersLeave( tracker, event, [ gPoint ] );
//TODO simulate mouseoout on IE < 9? // Simulate mouseoout on IE < 9
// if ( $.Browser.vendor === $.BROWSERS.IE && $.Browser.version < 9 ) { if ( !$.MouseTracker.havePointerOverOut ) {
// handleMouseOut( tracker, event ); handleMouseOut( tracker, event );
// } }
} }
@ -1992,10 +1989,6 @@
* @inner * @inner
*/ */
function onMouseOver( tracker, event ) { function onMouseOver( tracker, event ) {
// if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) {
// return;
// }
handleMouseOver( tracker, event ); handleMouseOver( tracker, event );
} }
@ -2024,10 +2017,6 @@
* @inner * @inner
*/ */
function onMouseOut( tracker, event ) { function onMouseOut( tracker, event ) {
// if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) {
// return;
// }
handleMouseOut( tracker, event ); handleMouseOut( tracker, event );
} }
@ -2435,9 +2424,18 @@
* @inner * @inner
*/ */
function onPointerEnter( tracker, event ) { function onPointerEnter( tracker, event ) {
handlePointerEnter( tracker, event );
}
/**
* @private
* @inner
*/
function handlePointerEnter( tracker, event ) {
var gPoint; var gPoint;
//$.console.log('pointerenter ' + (tracker.userData ? tracker.userData.toString() : '') + ' ' + (event.target === tracker.element ? 'tracker.element' : '')); //$.console.log('pointerenter ' + (tracker.userData ? tracker.userData.toString() : ''));
gPoint = { gPoint = {
id: event.pointerId, id: event.pointerId,
@ -2448,7 +2446,7 @@
}; };
updatePointersEnter( tracker, event, [ gPoint ] ); updatePointersEnter( tracker, event, [ gPoint ] );
} }
/** /**
@ -2456,9 +2454,18 @@
* @inner * @inner
*/ */
function onPointerLeave( tracker, event ) { function onPointerLeave( tracker, event ) {
handlePointerLeave( tracker, event );
}
/**
* @private
* @inner
*/
function handlePointerLeave( tracker, event ) {
var gPoint; var gPoint;
//$.console.log('pointerleave ' + (tracker.userData ? tracker.userData.toString() : '') + ' ' + (event.target === tracker.element ? 'tracker.element' : '')); //$.console.log('pointerleave ' + (tracker.userData ? tracker.userData.toString() : ''));
gPoint = { gPoint = {
id: event.pointerId, id: event.pointerId,
@ -2479,11 +2486,14 @@
function onPointerOver( tracker, event ) { function onPointerOver( tracker, event ) {
var gPoint; var gPoint;
$.console.log('pointerover ' + (tracker.userData ? tracker.userData.toString() : '') + ' ' + (event.target === tracker.element ? 'tracker.element' : '')); //$.console.log('pointerover ' + (tracker.userData ? tracker.userData.toString() : '') + ' ' + (event.target === tracker.element ? 'tracker.element' : ''));
//if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) { // If on IE 10, simulate MSPointerEnter
// return; if ( !$.MouseTracker.unprefixedPointerEvents &&
//} event.currentTarget !== event.relatedTarget &&
!isParentChild( event.currentTarget, event.relatedTarget ) ) {
handlePointerEnter( tracker, event );
}
gPoint = { gPoint = {
id: event.pointerId, id: event.pointerId,
@ -2504,11 +2514,14 @@
function onPointerOut( tracker, event ) { function onPointerOut( tracker, event ) {
var gPoint; var gPoint;
$.console.log('pointerout ' + (tracker.userData ? tracker.userData.toString() : '') + ' ' + (event.target === tracker.element ? 'tracker.element' : '')); //$.console.log('pointerout ' + (tracker.userData ? tracker.userData.toString() : '') + ' ' + (event.target === tracker.element ? 'tracker.element' : ''));
//if ( event.currentTarget === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) { // If on IE 10, simulate MSPointerLeave
// return; if ( !$.MouseTracker.unprefixedPointerEvents &&
//} event.currentTarget !== event.relatedTarget &&
!isParentChild( event.currentTarget, event.relatedTarget ) ) {
handlePointerLeave( tracker, event );
}
gPoint = { gPoint = {
id: event.pointerId, id: event.pointerId,

View file

@ -15,9 +15,9 @@
$.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" );
if ( $.Browser.vendor !== $.BROWSERS.IE || $.Browser.version > 8 ) { if ( $.Browser.vendor !== $.BROWSERS.IE || $.Browser.version > 8 ) {
$.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" );
$.MouseTracker.haveMouseOver = true; $.MouseTracker.havePointerOverOut = true;
} else { } else {
$.MouseTracker.haveMouseOver = false; $.MouseTracker.havePointerOverOut = false;
} }
$.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" );
if ( 'ontouchstart' in window ) { if ( 'ontouchstart' in window ) {
@ -33,7 +33,5 @@
$.MouseTracker.subscribeEvents.push( "gesturestart", "gesturechange" ); $.MouseTracker.subscribeEvents.push( "gesturestart", "gesturechange" );
} }
$.MouseTracker.mousePointerId = "legacy-mouse"; $.MouseTracker.mousePointerId = "legacy-mouse";
$.MouseTracker.maxTouchPoints = 10;
}(OpenSeadragon)); }(OpenSeadragon));