From e11095968c514965ddad1f1bb9e81f0b6a298234 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Mon, 4 Aug 2014 21:41:07 -0700 Subject: [PATCH 01/11] Mousetracker Over/Out Tracking Fixes --- src/button.js | 7 ++ src/buttongroup.js | 6 + src/mousetracker.js | 238 +++++++++++++++++++++++++++++++++----- src/navigator.js | 6 + src/openseadragon.js | 2 +- src/referencestrip.js | 11 ++ src/viewer.js | 8 +- test/legacy.mouse.shim.js | 10 +- 8 files changed, 251 insertions(+), 37 deletions(-) diff --git a/src/button.js b/src/button.js index a83d40a6..b399ccd1 100644 --- a/src/button.js +++ b/src/button.js @@ -137,6 +137,11 @@ $.Button = function( options ) { this.tooltip; this.element.style.position = "relative"; + if ( this.element.style[ "touch-action" ] !== undefined ) { + this.element.style[ "touch-action" ] = "none"; + } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { + this.element.style[ "-ms-touch-action" ] = "none"; + } this.imgGroup.style.position = this.imgHover.style.position = @@ -207,6 +212,7 @@ $.Button = function( options ) { clickDistThreshold: this.clickDistThreshold, enterHandler: function( event ) { + $.console.log('Enter ');// + event.currentTarget.className); if ( event.insideElementPressed ) { inTo( _this, $.ButtonState.DOWN ); /** @@ -241,6 +247,7 @@ $.Button = function( options ) { }, exitHandler: function( event ) { + $.console.log('Exit ');// + event.currentTarget.className); outTo( _this, $.ButtonState.GROUP ); if ( event.insideElementPressed ) { /** diff --git a/src/buttongroup.js b/src/buttongroup.js index a05e9084..51bb5642 100644 --- a/src/buttongroup.js +++ b/src/buttongroup.js @@ -80,6 +80,12 @@ $.ButtonGroup = function( options ) { } } + if ( this.element.style[ "touch-action" ] !== undefined ) { + this.element.style[ "touch-action" ] = "none"; + } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { + this.element.style[ "-ms-touch-action" ] = "none"; + } + /** * Tracks mouse/touch/key events accross the group of buttons. * @member {OpenSeadragon.MouseTracker} tracker diff --git a/src/mousetracker.js b/src/mousetracker.js index 03ed2b43..6d63b57f 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -205,6 +205,10 @@ gesturestart: function ( event ) { onGestureStart( _this, event ); }, gesturechange: function ( event ) { onGestureChange( _this, event ); }, + pointerover: function ( event ) { onPointerOver( _this, event ); }, + MSPointerOver: function ( event ) { onPointerOver( _this, event ); }, + pointerout: 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 ); }, @@ -217,6 +221,8 @@ MSPointerMove: function ( event ) { onPointerMove( _this, event ); }, pointercancel: function ( event ) { onPointerCancel( _this, event ); }, MSPointerCancel: function ( event ) { onPointerCancel( _this, event ); }, + pointerupcaptured: function ( event ) { onPointerUpCaptured( _this, event ); }, + pointermovecaptured: function ( event ) { onPointerMoveCaptured( _this, event ); }, tracking: false, @@ -812,32 +818,41 @@ } if ( window.PointerEvent ) { + $.console.log('***** Pointer Event Model'); // IE11 and other W3C Pointer Event implementations (see http://www.w3.org/TR/pointerevents) - $.MouseTracker.subscribeEvents.push( "pointerenter", "pointerleave", "pointerdown", "pointerup", "pointermove", "pointercancel" ); + $.MouseTracker.subscribeEvents.push( "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" ); $.MouseTracker.unprefixedPointerEvents = true; if( navigator.maxTouchPoints ) { $.MouseTracker.maxTouchPoints = navigator.maxTouchPoints; } else { $.MouseTracker.maxTouchPoints = 0; } - $.MouseTracker.haveTouchEnter = true; - $.MouseTracker.haveMouseEnter = true; + $.MouseTracker.haveTouchEnter = false; + $.MouseTracker.haveMouseEnter = false; } else if ( window.MSPointerEvent ) { + $.console.log('***** Pointer Event Model (Prefixed IE10)'); // IE10 - $.MouseTracker.subscribeEvents.push( "MSPointerEnter", "MSPointerLeave", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" ); + $.MouseTracker.subscribeEvents.push( "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" ); $.MouseTracker.unprefixedPointerEvents = false; if( navigator.msMaxTouchPoints ) { $.MouseTracker.maxTouchPoints = navigator.msMaxTouchPoints; } else { $.MouseTracker.maxTouchPoints = 0; } - $.MouseTracker.haveTouchEnter = true; - $.MouseTracker.haveMouseEnter = true; + $.MouseTracker.haveTouchEnter = false; + $.MouseTracker.haveMouseEnter = false; } else { + $.console.log('***** Legacy Event Model'); // Legacy W3C mouse events // TODO: Favor mouseenter/mouseleave over mouseover/mouseout when Webkit browser support is better - $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); - $.MouseTracker.haveMouseEnter = false; + $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); + //if ( $.Browser.vendor == $.BROWSERS.IE ) { + // $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); + // $.MouseTracker.haveMouseEnter = true; + //} else { + $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); + $.MouseTracker.haveMouseEnter = false; + //} if ( 'ontouchstart' in window ) { // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" ); @@ -1083,10 +1098,10 @@ var delegate = THIS[ tracker.hash ]; if ( !delegate.capturing ) { - if ( $.MouseTracker.supportsMouseCapture ) { - // IE<10, Firefox, other browsers with setCapture()/releaseCapture() - tracker.element.setCapture( true ); - } else { +// if ( $.MouseTracker.supportsMouseCapture ) { +// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() +// tracker.element.setCapture( true ); +// } else { // For browsers without setCapture()/releaseCapture(), 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) $.addEvent( @@ -1101,7 +1116,7 @@ delegate.mousemovecaptured, true ); - } +// } delegate.capturing = true; } } @@ -1116,10 +1131,10 @@ var delegate = THIS[ tracker.hash ]; if ( delegate.capturing ) { - if ( $.MouseTracker.supportsMouseCapture ) { - // IE<10, Firefox, other browsers with setCapture()/releaseCapture() - tracker.element.releaseCapture(); - } else { +// if ( $.MouseTracker.supportsMouseCapture ) { +// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() +// tracker.element.releaseCapture(); +// } else { // For browsers without setCapture()/releaseCapture(), 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) $.removeEvent( @@ -1134,7 +1149,7 @@ delegate.mouseupcaptured, true ); - } +// } delegate.capturing = false; } } @@ -1418,7 +1433,7 @@ event = $.getEvent( event ); - if ( this === event.relatedTarget || isParentChild( this, event.relatedTarget ) ) { + if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || return; } @@ -1443,7 +1458,7 @@ event = $.getEvent( event ); - if ( this === event.relatedTarget || isParentChild( this, event.relatedTarget ) ) { + if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || return; } @@ -1803,6 +1818,52 @@ } + /** + * @private + * @inner + */ + function onPointerOver( tracker, event ) { + var gPoint; + + if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || + return; + } + + gPoint = { + id: event.pointerId, + type: getPointerType( event ), + isPrimary: event.isPrimary, + currentPos: getMouseAbsolute( event ), + currentTime: $.now() + }; + + updatePointersEnter( tracker, event, [ gPoint ] ); + } + + + /** + * @private + * @inner + */ + function onPointerOut( tracker, event ) { + var gPoint; + + if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || + return; + } + + gPoint = { + id: event.pointerId, + type: getPointerType( event ), + isPrimary: event.isPrimary, + currentPos: getMouseAbsolute( event ), + currentTime: $.now() + }; + + updatePointersExit( tracker, event, [ gPoint ] ); + } + + /** * @private * @inner @@ -1841,6 +1902,72 @@ } + /** + * Begin capturing pointer events to the tracked element (pointer event model only). + * @private + * @inner + */ + function capturePointer( tracker ) { + var delegate = THIS[ tracker.hash ]; + + if ( !delegate.capturing ) { +// if ( $.MouseTracker.supportsMouseCapture ) { +// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() +// tracker.element.setCapture( true ); +// } else { + // For browsers without setCapture()/releaseCapture(), 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) + $.addEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', + delegate.pointerupcaptured, + true + ); + $.addEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', + delegate.pointermovecaptured, + true + ); +// } + delegate.capturing = true; + } + } + + + /** + * Stop capturing pointer events to the tracked element (pointer event model only). + * @private + * @inner + */ + function releasePointer( tracker ) { + var delegate = THIS[ tracker.hash ]; + + if ( delegate.capturing ) { +// if ( $.MouseTracker.supportsMouseCapture ) { +// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() +// tracker.element.releaseCapture(); +// } else { + // For browsers without setCapture()/releaseCapture(), 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) + $.removeEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', + delegate.pointermovecaptured, + true + ); + $.removeEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', + delegate.pointerupcaptured, + true + ); +// } + delegate.capturing = false; + } + } + + /** * @private * @inner @@ -1857,11 +1984,12 @@ }; if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { - if ( $.MouseTracker.unprefixedPointerEvents ) { - event.currentTarget.setPointerCapture( event.pointerId ); - } else { - event.currentTarget.msSetPointerCapture( event.pointerId ); - } +// if ( $.MouseTracker.unprefixedPointerEvents ) { +// event.currentTarget.setPointerCapture( event.pointerId ); +// } else { +// event.currentTarget.msSetPointerCapture( event.pointerId ); +// } + capturePointer( tracker ); $.stopEvent( event ); } @@ -1876,6 +2004,28 @@ * @inner */ function onPointerUp( tracker, event ) { + handlePointerUp( tracker, event ); + } + + + /** + * This handler is attached to the window object (on the capture phase) to emulate mouse capture. + * onPointerUp is still attached to the tracked element, so stop propagation to avoid processing twice. + * + * @private + * @inner + */ + function onPointerUpCaptured( tracker, event ) { + handlePointerUp( tracker, event ); + $.stopEvent( event ); + } + + + /** + * @private + * @inner + */ + function handlePointerUp( tracker, event ) { var gPoint; gPoint = { @@ -1887,11 +2037,13 @@ }; if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { - if ( $.MouseTracker.unprefixedPointerEvents ) { - event.currentTarget.releasePointerCapture( event.pointerId ); - } else { - event.currentTarget.msReleasePointerCapture( event.pointerId ); - } +// if ( $.MouseTracker.unprefixedPointerEvents ) { +// event.currentTarget.releasePointerCapture( event.pointerId ); +// } else { +// event.currentTarget.msReleasePointerCapture( event.pointerId ); +// } + releasePointer( tracker ); +// $.stopEvent( event ); } } @@ -1901,6 +2053,28 @@ * @inner */ function onPointerMove( tracker, event ) { + handlePointerMove( tracker, event ); + } + + + /** + * This handler is attached to the window object (on the capture phase) to emulate mouse capture. + * onPointerMove is still attached to the tracked element, so stop propagation to avoid processing twice. + * + * @private + * @inner + */ + function onPointerMoveCaptured( tracker, event ) { + handlePointerMove( tracker, event ); + $.stopEvent( event ); + } + + + /** + * @private + * @inner + */ + function handlePointerMove( tracker, event ) { // Pointer changed coordinates, button state, pressure, tilt, or contact geometry (e.g. width and height) var gPoint; @@ -1964,6 +2138,7 @@ gPoint.lastPos = gPoint.currentPos; gPoint.lastTime = gPoint.currentTime; +// $.console.log('startTrackingPointer() ', pointsList.getLength() + 1); return pointsList.add( gPoint ); } @@ -1999,6 +2174,7 @@ listLength = pointsList.getLength(); } +// $.console.log('stopTrackingPointer() ', listLength); return listLength; } @@ -2213,6 +2389,7 @@ } pointsList.contacts++; + $.console.log('contacts++ ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { $.MouseTracker.gesturePointVelocityTracker.addPoint( tracker, curGPoint ); @@ -2339,6 +2516,7 @@ // Pointer was activated in our element but could have been removed in any element since events are captured to our element pointsList.contacts--; + $.console.log('contacts-- ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { $.MouseTracker.gesturePointVelocityTracker.removePoint( tracker, updateGPoint ); diff --git a/src/navigator.js b/src/navigator.js index 2043a8f4..d27e58cf 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -112,6 +112,12 @@ $.Navigator = function( options ){ options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio; + if ( this.element.style[ "touch-action" ] !== undefined ) { + this.element.style[ "touch-action" ] = "none"; + } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { + this.element.style[ "-ms-touch-action" ] = "none"; + } + this.borderWidth = 2; //At some browser magnification levels the display regions lines up correctly, but at some there appears to //be a one pixel gap. diff --git a/src/openseadragon.js b/src/openseadragon.js index 14ddd3d5..9b98ff76 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -2161,7 +2161,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ ) ); } else { - regex = new RegExp( "Trident/.*rv:([0-9]{1,}[.0-9]{0,}) "); + regex = new RegExp( "Trident/.*rv:([0-9]{1,}[.0-9]{0,})"); if ( regex.exec( ua ) !== null ) { $.Browser.vendor = $.BROWSERS.IE; $.Browser.version = parseFloat( RegExp.$1 ); diff --git a/src/referencestrip.js b/src/referencestrip.js index b7192517..c344c880 100644 --- a/src/referencestrip.js +++ b/src/referencestrip.js @@ -114,6 +114,12 @@ $.ReferenceStrip = function ( options ) { style.background = '#000'; style.position = 'relative'; + if ( this.element.style[ "touch-action" ] !== undefined ) { + this.element.style[ "touch-action" ] = "none"; + } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { + this.element.style[ "-ms-touch-action" ] = "none"; + } + $.setElementOpacity( this.element, 0.8 ); this.viewer = viewer; @@ -189,6 +195,11 @@ $.ReferenceStrip = function ( options ) { element.style.cssFloat = 'left'; //Firefox element.style.styleFloat = 'left'; //IE element.style.padding = '2px'; + if ( element.style[ "touch-action" ] !== undefined ) { + element.style[ "touch-action" ] = "none"; + } else if ( element.style[ "-ms-touch-action" ] !== undefined ) { + element.style[ "-ms-touch-action" ] = "none"; + } element.innerTracker = new $.MouseTracker( { element: element, diff --git a/src/viewer.js b/src/viewer.js index aa4daa64..27a24cb2 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -276,10 +276,10 @@ $.Viewer = function( options ) { style.top = "0px"; style.left = "0px"; // Disable browser default touch handling - if (style["touch-action"] !== undefined) { - style["touch-action"] = "none"; - } else if (style["-ms-touch-action"] !== undefined) { - style["-ms-touch-action"] = "none"; + if ( style[ "touch-action" ] !== undefined ) { + style[ "touch-action" ] = "none"; + } else if ( style["-ms-touch-action"] !== undefined ) { + style[ "-ms-touch-action" ] = "none"; } }(this.canvas.style)); diff --git a/test/legacy.mouse.shim.js b/test/legacy.mouse.shim.js index 7a8ff7cc..4d27c39a 100644 --- a/test/legacy.mouse.shim.js +++ b/test/legacy.mouse.shim.js @@ -11,8 +11,14 @@ $.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" ); } - $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); - $.MouseTracker.haveMouseEnter = false; + $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); + if ( $.Browser.vendor == $.BROWSERS.IE ) { + $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); + $.MouseTracker.haveMouseEnter = true; + } else { + $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); + $.MouseTracker.haveMouseEnter = false; + } if ( 'ontouchstart' in window ) { // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" ); From 4152b8b8661f45029641009cf78d9e1f521f0d58 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Tue, 5 Aug 2014 07:13:06 -0700 Subject: [PATCH 02/11] Trailing whitespace fixes --- src/iiiftilesource.js | 10 +++++----- src/tilesource.js | 2 +- src/viewport.js | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/iiiftilesource.js b/src/iiiftilesource.js index a18a9a2b..8c1da291 100644 --- a/src/iiiftilesource.js +++ b/src/iiiftilesource.js @@ -98,9 +98,9 @@ $.IIIFTileSource = function( options ){ } if ( !options.maxLevel ) { - if ( !this.scale_factors ) { - options.maxLevel = Number( Math.ceil( Math.log( Math.max( this.width, this.height ), 2 ) ) ); - } else { + if ( !this.scale_factors ) { + options.maxLevel = Number( Math.ceil( Math.log( Math.max( this.width, this.height ), 2 ) ) ); + } else { options.maxLevel = Math.floor( Math.pow( Math.max.apply(null, this.scale_factors), 0.5) ); } } @@ -128,7 +128,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea return true; // Version 1.0 - } else if ( data.profile && + } else if ( data.profile && data.profile.indexOf("http://library.stanford.edu/iiif/image-api/compliance.html") === 0) { return true; } else if ( data.identifier && data.width && data.height ) { @@ -166,7 +166,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea configure: function( data, url ){ // Try to deduce our version and fake it upwards if needed if ( !$.isPlainObject(data) ) { - var options = configureFromXml10( data ); + var options = configureFromXml10( data ); options['@context'] = "http://iiif.io/api/image/1.0/context.json"; options['@id'] = url.replace('/info.xml', ''); return options; diff --git a/src/tilesource.js b/src/tilesource.js index 9fc1f7d8..deecc742 100644 --- a/src/tilesource.js +++ b/src/tilesource.js @@ -263,7 +263,7 @@ $.TileSource.prototype = /** @lends OpenSeadragon.TileSource.prototype */{ tiles; for( i = this.minLevel; i < this.maxLevel; i++ ){ tiles = this.getNumTiles( i ); - tilesPerSide = Math.floor( Math.max( rect.x, rect.y ) / this.getTileSize(i) ); + tilesPerSide = Math.floor( Math.max( rect.x, rect.y ) / this.getTileSize(i) ); if( Math.max( tiles.x, tiles.y ) + 1 >= tilesPerSide ){ break; } diff --git a/src/viewport.js b/src/viewport.js index 7bceb9d8..38ecfa27 100644 --- a/src/viewport.js +++ b/src/viewport.js @@ -326,7 +326,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{ * @param {OpenSeadragon.Rect} bounds * @param {Boolean} immediately * @return {OpenSeadragon.Rect} constrained bounds. - */ + */ _applyBoundaryConstraints: function( bounds, immediately ) { var horizontalThreshold, verticalThreshold, @@ -402,9 +402,9 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{ this.viewer.raiseEvent( 'constrain', { immediately: immediately }); - } + } - return newBounds; + return newBounds; }, /** @@ -523,7 +523,7 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{ ); return this.zoomTo( newZoom, referencePoint, immediately ); - }, + }, /** * @function From 3521bac90e2651ca5df61e8e297611136be7cefc Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Tue, 5 Aug 2014 13:56:18 -0700 Subject: [PATCH 03/11] Fixed pointer event capture, Cleaned up debug code --- src/button.js | 2 - src/mousetracker.js | 339 +++++++++++++------------------------- src/navigator.js | 15 +- test/legacy.mouse.shim.js | 10 +- 4 files changed, 116 insertions(+), 250 deletions(-) diff --git a/src/button.js b/src/button.js index b399ccd1..0066efb9 100644 --- a/src/button.js +++ b/src/button.js @@ -212,7 +212,6 @@ $.Button = function( options ) { clickDistThreshold: this.clickDistThreshold, enterHandler: function( event ) { - $.console.log('Enter ');// + event.currentTarget.className); if ( event.insideElementPressed ) { inTo( _this, $.ButtonState.DOWN ); /** @@ -247,7 +246,6 @@ $.Button = function( options ) { }, exitHandler: function( event ) { - $.console.log('Exit ');// + event.currentTarget.className); outTo( _this, $.ButtonState.GROUP ); if ( event.insideElementPressed ) { /** diff --git a/src/mousetracker.js b/src/mousetracker.js index fedd0295..8e096b6e 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -122,28 +122,28 @@ * @member {Number} clickTimeThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.clickTimeThreshold = options.clickTimeThreshold; + this.clickTimeThreshold = options.clickTimeThreshold || $.DEFAULT_SETTINGS.clickTimeThreshold; /** * The maximum distance allowed between a pointer down event and a pointer up event * to be treated as a click gesture. * @member {Number} clickDistThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.clickDistThreshold = options.clickDistThreshold; + this.clickDistThreshold = options.clickDistThreshold || $.DEFAULT_SETTINGS.clickDistThreshold; /** * The number of milliseconds within which two pointer down-up event combinations * will be treated as a double-click gesture. * @member {Number} dblClickTimeThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.dblClickTimeThreshold = options.dblClickTimeThreshold; + this.dblClickTimeThreshold = options.dblClickTimeThreshold || $.DEFAULT_SETTINGS.dblClickTimeThreshold; /** * The maximum distance allowed between two pointer click events * to be treated as a click gesture. * @member {Number} clickDistThreshold * @memberof OpenSeadragon.MouseTracker# */ - this.dblClickDistThreshold = options.dblClickDistThreshold; + this.dblClickDistThreshold = options.dblClickDistThreshold || $.DEFAULT_SETTINGS.dblClickDistThreshold; this.userData = options.userData || null; this.stopDelay = options.stopDelay || 50; @@ -187,8 +187,6 @@ mouseover: function ( event ) { onMouseOver( _this, event ); }, mouseout: function ( event ) { onMouseOut( _this, event ); }, - mouseenter: function ( event ) { onMouseEnter( _this, event ); }, - mouseleave: function ( event ) { onMouseLeave( _this, event ); }, mousedown: function ( event ) { onMouseDown( _this, event ); }, mouseup: function ( event ) { onMouseUp( _this, event ); }, mouseupcaptured: function ( event ) { onMouseUpCaptured( _this, event ); }, @@ -209,10 +207,6 @@ MSPointerOver: function ( event ) { onPointerOver( _this, event ); }, pointerout: 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 ); }, MSPointerDown: function ( event ) { onPointerDown( _this, event ); }, pointerup: function ( event ) { onPointerUp( _this, event ); }, @@ -232,9 +226,12 @@ // of the element (for hover-capable devices) and/or have contact or a button press initiated in the element. activePointersLists: [], - // Legacy mouse event tracking + // Legacy mouse capture tracking capturing: false, + // Pointer event model capture tracking + pointerCaptureCount: 0, + // Tracking for double-click gesture lastClickPos: null, dblClickTimeOut: null, @@ -821,7 +818,6 @@ } if ( window.PointerEvent ) { - $.console.log('***** Pointer Event Model'); // IE11 and other W3C Pointer Event implementations (see http://www.w3.org/TR/pointerevents) $.MouseTracker.subscribeEvents.push( "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel" ); $.MouseTracker.unprefixedPointerEvents = true; @@ -833,7 +829,6 @@ $.MouseTracker.haveTouchEnter = false; $.MouseTracker.haveMouseEnter = false; } else if ( window.MSPointerEvent ) { - $.console.log('***** Pointer Event Model (Prefixed IE10)'); // IE10 $.MouseTracker.subscribeEvents.push( "MSPointerOver", "MSPointerOut", "MSPointerDown", "MSPointerUp", "MSPointerMove", "MSPointerCancel" ); $.MouseTracker.unprefixedPointerEvents = false; @@ -845,17 +840,9 @@ $.MouseTracker.haveTouchEnter = false; $.MouseTracker.haveMouseEnter = false; } else { - $.console.log('***** Legacy Event Model'); // Legacy W3C mouse events - // TODO: Favor mouseenter/mouseleave over mouseover/mouseout when Webkit browser support is better - $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); - //if ( $.Browser.vendor == $.BROWSERS.IE ) { - // $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); - // $.MouseTracker.haveMouseEnter = true; - //} else { - $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); - $.MouseTracker.haveMouseEnter = false; - //} + $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); + $.MouseTracker.haveMouseEnter = false; if ( 'ontouchstart' in window ) { // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" ); @@ -1101,25 +1088,20 @@ var delegate = THIS[ tracker.hash ]; if ( !delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.setCapture( true ); -// } else { - // For browsers without setCapture()/releaseCapture(), 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) - $.addEvent( - window, - "mouseup", - delegate.mouseupcaptured, - true - ); - $.addEvent( - window, - "mousemove", - delegate.mousemovecaptured, - true - ); -// } + // 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) + $.addEvent( + window, + "mouseup", + delegate.mouseupcaptured, + true + ); + $.addEvent( + window, + "mousemove", + delegate.mousemovecaptured, + true + ); delegate.capturing = true; } } @@ -1134,25 +1116,82 @@ var delegate = THIS[ tracker.hash ]; if ( delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.releaseCapture(); -// } else { - // For browsers without setCapture()/releaseCapture(), 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) - $.removeEvent( - window, - "mousemove", - delegate.mousemovecaptured, - true - ); - $.removeEvent( - window, - "mouseup", - delegate.mouseupcaptured, - true - ); -// } + // 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) + $.removeEvent( + window, + "mousemove", + delegate.mousemovecaptured, + true + ); + $.removeEvent( + window, + "mouseup", + delegate.mouseupcaptured, + true + ); + delegate.capturing = false; + } + } + + + /** + * Begin capturing pointer events to the tracked element (pointer event model only). + * @private + * @inner + */ + function capturePointer( tracker ) { + var delegate = THIS[ tracker.hash ]; + + delegate.pointerCaptureCount++; + //$.console.log('pointerCaptureCount++ ', delegate.pointerCaptureCount); + + if ( delegate.pointerCaptureCount === 1 ) { + // 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) + $.addEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', + delegate.pointerupcaptured, + true + ); + $.addEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', + delegate.pointermovecaptured, + true + ); + delegate.capturing = true; + } + } + + + /** + * Stop capturing pointer events to the tracked element (pointer event model only). + * @private + * @inner + */ + function releasePointer( tracker ) { + var delegate = THIS[ tracker.hash ]; + + delegate.pointerCaptureCount--; + //$.console.log('pointerCaptureCount-- ', delegate.pointerCaptureCount); + + if ( delegate.pointerCaptureCount === 0 ) { + // 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) + $.removeEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', + delegate.pointermovecaptured, + true + ); + $.removeEvent( + window, + $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', + delegate.pointerupcaptured, + true + ); delegate.capturing = false; } } @@ -1477,48 +1516,6 @@ } - /** - * @private - * @inner - */ - function onMouseEnter( tracker, event ) { - var gPoint; - - event = $.getEvent( event ); - - gPoint = { - id: $.MouseTracker.mousePointerId, - type: 'mouse', - isPrimary: true, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersEnter( tracker, event, [ gPoint ] ); - } - - - /** - * @private - * @inner - */ - function onMouseLeave( tracker, event ) { - var gPoint; - - event = $.getEvent( event ); - - gPoint = { - id: $.MouseTracker.mousePointerId, - type: 'mouse', - isPrimary: true, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersExit( tracker, event, [ gPoint ] ); - } - - /** * @private * @inner @@ -1557,8 +1554,6 @@ /** * This handler is attached to the window object (on the capture phase) to emulate mouse capture. - * Only triggered in W3C browsers that don't have setCapture/releaseCapture - * methods or don't support the new pointer events model. * onMouseUp is still attached to the tracked element, so stop propagation to avoid processing twice. * * @private @@ -1604,8 +1599,6 @@ /** * This handler is attached to the window object (on the capture phase) to emulate mouse capture. - * Only triggered in W3C browsers that don't have setCapture/releaseCapture - * methods or don't support the new pointer events model. * onMouseMove is still attached to the tracked element, so stop propagation to avoid processing twice. * * @private @@ -1867,110 +1860,6 @@ } - /** - * @private - * @inner - */ - function onPointerEnter( tracker, event ) { - var gPoint; - - gPoint = { - id: event.pointerId, - type: getPointerType( event ), - isPrimary: event.isPrimary, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersEnter( tracker, event, [ gPoint ] ); - } - - - /** - * @private - * @inner - */ - function onPointerLeave( tracker, event ) { - var gPoint; - - gPoint = { - id: event.pointerId, - type: getPointerType( event ), - isPrimary: event.isPrimary, - currentPos: getMouseAbsolute( event ), - currentTime: $.now() - }; - - updatePointersExit( tracker, event, [ gPoint ] ); - } - - - /** - * Begin capturing pointer events to the tracked element (pointer event model only). - * @private - * @inner - */ - function capturePointer( tracker ) { - var delegate = THIS[ tracker.hash ]; - - if ( !delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.setCapture( true ); -// } else { - // For browsers without setCapture()/releaseCapture(), 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) - $.addEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', - delegate.pointerupcaptured, - true - ); - $.addEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', - delegate.pointermovecaptured, - true - ); -// } - delegate.capturing = true; - } - } - - - /** - * Stop capturing pointer events to the tracked element (pointer event model only). - * @private - * @inner - */ - function releasePointer( tracker ) { - var delegate = THIS[ tracker.hash ]; - - if ( delegate.capturing ) { -// if ( $.MouseTracker.supportsMouseCapture ) { -// // IE<10, Firefox, other browsers with setCapture()/releaseCapture() -// tracker.element.releaseCapture(); -// } else { - // For browsers without setCapture()/releaseCapture(), 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) - $.removeEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', - delegate.pointermovecaptured, - true - ); - $.removeEvent( - window, - $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', - delegate.pointerupcaptured, - true - ); -// } - delegate.capturing = false; - } - } - - /** * @private * @inner @@ -1987,11 +1876,6 @@ }; if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { -// if ( $.MouseTracker.unprefixedPointerEvents ) { -// event.currentTarget.setPointerCapture( event.pointerId ); -// } else { -// event.currentTarget.msSetPointerCapture( event.pointerId ); -// } capturePointer( tracker ); $.stopEvent( event ); } @@ -2019,7 +1903,10 @@ * @inner */ function onPointerUpCaptured( tracker, event ) { - handlePointerUp( tracker, event ); + var pointsList = tracker.getActivePointersListByType( getPointerType( event ) ); + if ( pointsList.getById( event.pointerId ) ) { + handlePointerUp( tracker, event ); + } $.stopEvent( event ); } @@ -2040,13 +1927,8 @@ }; if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { -// if ( $.MouseTracker.unprefixedPointerEvents ) { -// event.currentTarget.releasePointerCapture( event.pointerId ); -// } else { -// event.currentTarget.msReleasePointerCapture( event.pointerId ); -// } releasePointer( tracker ); -// $.stopEvent( event ); + //$.stopEvent( event ); } } @@ -2068,7 +1950,10 @@ * @inner */ function onPointerMoveCaptured( tracker, event ) { - handlePointerMove( tracker, event ); + var pointsList = tracker.getActivePointersListByType( getPointerType( event ) ); + if ( pointsList.getById( event.pointerId ) ) { + handlePointerMove( tracker, event ); + } $.stopEvent( event ); } @@ -2141,7 +2026,6 @@ gPoint.lastPos = gPoint.currentPos; gPoint.lastTime = gPoint.currentTime; -// $.console.log('startTrackingPointer() ', pointsList.getLength() + 1); return pointsList.add( gPoint ); } @@ -2177,7 +2061,6 @@ listLength = pointsList.getLength(); } -// $.console.log('stopTrackingPointer() ', listLength); return listLength; } @@ -2392,7 +2275,7 @@ } pointsList.contacts++; - $.console.log('contacts++ ', pointsList.contacts); + //$.console.log('contacts++ ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { $.MouseTracker.gesturePointVelocityTracker.addPoint( tracker, curGPoint ); @@ -2519,7 +2402,7 @@ // Pointer was activated in our element but could have been removed in any element since events are captured to our element pointsList.contacts--; - $.console.log('contacts-- ', pointsList.contacts); + //$.console.log('contacts-- ', pointsList.contacts); if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) { $.MouseTracker.gesturePointVelocityTracker.removePoint( tracker, updateGPoint ); diff --git a/src/navigator.js b/src/navigator.js index 20082900..a3fda4f5 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -321,17 +321,9 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /* * @function */ function onCanvasClick( event ) { - var newBounds, - viewerPosition, - dimensions; - if (! this.drag) { - if ( this.viewer.viewport ) { - this.viewer.viewport.panTo( this.viewport.pointFromPixel( event.position ) ); - this.viewer.viewport.applyConstraints(); - } - } - else { - this.drag = false; + if ( event.quick && this.viewer.viewport ) { + this.viewer.viewport.panTo( this.viewport.pointFromPixel( event.position ) ); + this.viewer.viewport.applyConstraints(); } } @@ -342,7 +334,6 @@ function onCanvasClick( event ) { */ function onCanvasDrag( event ) { if ( this.viewer.viewport ) { - this.drag = true; if( !this.panHorizontal ){ event.delta.x = 0; } diff --git a/test/legacy.mouse.shim.js b/test/legacy.mouse.shim.js index 4d27c39a..7a8ff7cc 100644 --- a/test/legacy.mouse.shim.js +++ b/test/legacy.mouse.shim.js @@ -11,14 +11,8 @@ $.MouseTracker.subscribeEvents.push( "MozMousePixelScroll" ); } - $.MouseTracker.subscribeEvents.push( "mousedown", "mouseup", "mousemove" ); - if ( $.Browser.vendor == $.BROWSERS.IE ) { - $.MouseTracker.subscribeEvents.push( "mouseenter", "mouseleave" ); - $.MouseTracker.haveMouseEnter = true; - } else { - $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout" ); - $.MouseTracker.haveMouseEnter = false; - } + $.MouseTracker.subscribeEvents.push( "mouseover", "mouseout", "mousedown", "mouseup", "mousemove" ); + $.MouseTracker.haveMouseEnter = false; if ( 'ontouchstart' in window ) { // iOS, Android, and other W3c Touch Event implementations (see http://www.w3.org/TR/2011/WD-touch-events-20110505) $.MouseTracker.subscribeEvents.push( "touchstart", "touchend", "touchmove", "touchcancel" ); From bf19e73f5eee7453ef4948da8410c593ca5ab241 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Tue, 5 Aug 2014 16:01:43 -0700 Subject: [PATCH 04/11] touch-action fixup --- src/button.js | 8 ++++---- src/buttongroup.js | 8 ++++---- src/navigator.js | 8 ++++---- src/referencestrip.js | 16 ++++++++-------- src/viewer.js | 8 ++++---- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/button.js b/src/button.js index 0066efb9..60eb450d 100644 --- a/src/button.js +++ b/src/button.js @@ -137,10 +137,10 @@ $.Button = function( options ) { this.tooltip; this.element.style.position = "relative"; - if ( this.element.style[ "touch-action" ] !== undefined ) { - this.element.style[ "touch-action" ] = "none"; - } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { - this.element.style[ "-ms-touch-action" ] = "none"; + if ( typeof this.element.style.touchAction !== 'undefined' ) { + this.element.style.touchAction = 'none'; + } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { + this.element.style.msTouchAction = 'none'; } this.imgGroup.style.position = diff --git a/src/buttongroup.js b/src/buttongroup.js index 51bb5642..977d616a 100644 --- a/src/buttongroup.js +++ b/src/buttongroup.js @@ -80,10 +80,10 @@ $.ButtonGroup = function( options ) { } } - if ( this.element.style[ "touch-action" ] !== undefined ) { - this.element.style[ "touch-action" ] = "none"; - } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { - this.element.style[ "-ms-touch-action" ] = "none"; + if ( typeof this.element.style.touchAction !== 'undefined' ) { + this.element.style.touchAction = 'none'; + } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { + this.element.style.msTouchAction = 'none'; } /** diff --git a/src/navigator.js b/src/navigator.js index a3fda4f5..410f99b8 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -112,10 +112,10 @@ $.Navigator = function( options ){ options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio; - if ( this.element.style[ "touch-action" ] !== undefined ) { - this.element.style[ "touch-action" ] = "none"; - } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { - this.element.style[ "-ms-touch-action" ] = "none"; + if ( typeof this.element.style.touchAction !== 'undefined' ) { + this.element.style.touchAction = 'none'; + } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { + this.element.style.msTouchAction = 'none'; } this.borderWidth = 2; diff --git a/src/referencestrip.js b/src/referencestrip.js index c344c880..6a70c634 100644 --- a/src/referencestrip.js +++ b/src/referencestrip.js @@ -114,10 +114,10 @@ $.ReferenceStrip = function ( options ) { style.background = '#000'; style.position = 'relative'; - if ( this.element.style[ "touch-action" ] !== undefined ) { - this.element.style[ "touch-action" ] = "none"; - } else if ( this.element.style[ "-ms-touch-action" ] !== undefined ) { - this.element.style[ "-ms-touch-action" ] = "none"; + if ( typeof this.element.style.touchAction !== 'undefined' ) { + this.element.style.touchAction = 'none'; + } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { + this.element.style.msTouchAction = 'none'; } $.setElementOpacity( this.element, 0.8 ); @@ -195,10 +195,10 @@ $.ReferenceStrip = function ( options ) { element.style.cssFloat = 'left'; //Firefox element.style.styleFloat = 'left'; //IE element.style.padding = '2px'; - if ( element.style[ "touch-action" ] !== undefined ) { - element.style[ "touch-action" ] = "none"; - } else if ( element.style[ "-ms-touch-action" ] !== undefined ) { - element.style[ "-ms-touch-action" ] = "none"; + if ( typeof element.style.touchAction !== 'undefined' ) { + element.style.touchAction = 'none'; + } else if ( typeof element.style.msTouchAction !== 'undefined' ) { + element.style.msTouchAction = 'none'; } element.innerTracker = new $.MouseTracker( { diff --git a/src/viewer.js b/src/viewer.js index 3575db9e..6558480b 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -276,10 +276,10 @@ $.Viewer = function( options ) { style.top = "0px"; style.left = "0px"; // Disable browser default touch handling - if ( style[ "touch-action" ] !== undefined ) { - style[ "touch-action" ] = "none"; - } else if ( style["-ms-touch-action"] !== undefined ) { - style[ "-ms-touch-action" ] = "none"; + if ( typeof style.touchAction !== 'undefined' ) { + style.touchAction = 'none'; + } else if ( typeof style.msTouchAction !== 'undefined' ) { + style.msTouchAction = 'none'; } }(this.canvas.style)); From be13d25a26fb727ff4ea811ade7031c30e38678a Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Tue, 5 Aug 2014 16:17:40 -0700 Subject: [PATCH 05/11] Removed debug code --- src/mousetracker.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mousetracker.js b/src/mousetracker.js index 8e096b6e..98308ab0 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -1475,7 +1475,7 @@ event = $.getEvent( event ); - if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || + if ( this === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) { return; } @@ -1500,7 +1500,7 @@ event = $.getEvent( event ); - if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || + if ( this === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) { return; } @@ -1821,7 +1821,7 @@ function onPointerOver( tracker, event ) { var gPoint; - if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || + if ( this === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) { return; } @@ -1844,7 +1844,7 @@ function onPointerOut( tracker, event ) { var gPoint; - if ( isParentChild( event.currentTarget, event.relatedTarget ) ) {//this === event.relatedTarget || + if ( this === event.relatedTarget || isParentChild( event.currentTarget, event.relatedTarget ) ) { return; } From e9b763449941a871ac2647516d4238400e40b261 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Tue, 5 Aug 2014 16:57:54 -0700 Subject: [PATCH 06/11] Added $.setElementTouchActionNone function --- src/button.js | 6 +----- src/buttongroup.js | 6 +----- src/navigator.js | 6 +----- src/openseadragon.js | 15 +++++++++++++++ src/referencestrip.js | 12 ++---------- src/viewer.js | 7 +------ 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/button.js b/src/button.js index 60eb450d..104955e0 100644 --- a/src/button.js +++ b/src/button.js @@ -137,11 +137,7 @@ $.Button = function( options ) { this.tooltip; this.element.style.position = "relative"; - if ( typeof this.element.style.touchAction !== 'undefined' ) { - this.element.style.touchAction = 'none'; - } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { - this.element.style.msTouchAction = 'none'; - } + $.setElementTouchActionNone( this.element ); this.imgGroup.style.position = this.imgHover.style.position = diff --git a/src/buttongroup.js b/src/buttongroup.js index 977d616a..2837805a 100644 --- a/src/buttongroup.js +++ b/src/buttongroup.js @@ -80,11 +80,7 @@ $.ButtonGroup = function( options ) { } } - if ( typeof this.element.style.touchAction !== 'undefined' ) { - this.element.style.touchAction = 'none'; - } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { - this.element.style.msTouchAction = 'none'; - } + $.setElementTouchActionNone( this.element ); /** * Tracks mouse/touch/key events accross the group of buttons. diff --git a/src/navigator.js b/src/navigator.js index 410f99b8..24d35a3d 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -112,11 +112,7 @@ $.Navigator = function( options ){ options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio; - if ( typeof this.element.style.touchAction !== 'undefined' ) { - this.element.style.touchAction = 'none'; - } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { - this.element.style.msTouchAction = 'none'; - } + $.setElementTouchActionNone( this.element ); this.borderWidth = 2; //At some browser magnification levels the display regions lines up correctly, but at some there appears to diff --git a/src/openseadragon.js b/src/openseadragon.js index e628ff88..5bccc84b 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -1585,6 +1585,21 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ }, + /** + * Sets the specified element's touch-action style attribute to 'none'. + * @function + * @param {Element|String} element + */ + setElementTouchActionNone: function( element ) { + element = $.getElement( element ); + if ( typeof element.style.touchAction !== 'undefined' ) { + element.style.touchAction = 'none'; + } else if ( typeof element.style.msTouchAction !== 'undefined' ) { + element.style.msTouchAction = 'none'; + } + }, + + /** * Add the specified CSS class to the element if not present. * @function diff --git a/src/referencestrip.js b/src/referencestrip.js index 6a70c634..f68744b2 100644 --- a/src/referencestrip.js +++ b/src/referencestrip.js @@ -114,11 +114,7 @@ $.ReferenceStrip = function ( options ) { style.background = '#000'; style.position = 'relative'; - if ( typeof this.element.style.touchAction !== 'undefined' ) { - this.element.style.touchAction = 'none'; - } else if ( typeof this.element.style.msTouchAction !== 'undefined' ) { - this.element.style.msTouchAction = 'none'; - } + $.setElementTouchActionNone( this.element ); $.setElementOpacity( this.element, 0.8 ); @@ -195,11 +191,7 @@ $.ReferenceStrip = function ( options ) { element.style.cssFloat = 'left'; //Firefox element.style.styleFloat = 'left'; //IE element.style.padding = '2px'; - if ( typeof element.style.touchAction !== 'undefined' ) { - element.style.touchAction = 'none'; - } else if ( typeof element.style.msTouchAction !== 'undefined' ) { - element.style.msTouchAction = 'none'; - } + $.setElementTouchActionNone( element ); element.innerTracker = new $.MouseTracker( { element: element, diff --git a/src/viewer.js b/src/viewer.js index 6558480b..46d6a527 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -275,13 +275,8 @@ $.Viewer = function( options ) { style.position = "absolute"; style.top = "0px"; style.left = "0px"; - // Disable browser default touch handling - if ( typeof style.touchAction !== 'undefined' ) { - style.touchAction = 'none'; - } else if ( typeof style.msTouchAction !== 'undefined' ) { - style.msTouchAction = 'none'; - } }(this.canvas.style)); + $.setElementTouchActionNone( this.canvas ); //the container is created through applying the ControlDock constructor above this.container.className = "openseadragon-container"; From ee3ab7002522f2fd653710b9c1ecaeccb169cd24 Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Wed, 6 Aug 2014 10:49:42 -0700 Subject: [PATCH 07/11] Combined redundant captureMouse()/capturePointer() and releaseMouse()/releasePointer() functions --- src/mousetracker.js | 91 ++++++++------------------------------------- 1 file changed, 16 insertions(+), 75 deletions(-) diff --git a/src/mousetracker.js b/src/mousetracker.js index 98308ab0..7a4df604 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -1074,73 +1074,16 @@ ); } - releaseMouse( tracker ); delegate.tracking = false; } } /** - * Begin capturing mouse events to the tracked element (legacy mouse events only). + * Begin capturing pointer events to the tracked element. * @private * @inner */ - function captureMouse( tracker ) { - var delegate = THIS[ tracker.hash ]; - - if ( !delegate.capturing ) { - // 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) - $.addEvent( - window, - "mouseup", - delegate.mouseupcaptured, - true - ); - $.addEvent( - window, - "mousemove", - delegate.mousemovecaptured, - true - ); - delegate.capturing = true; - } - } - - - /** - * Stop capturing mouse events to the tracked element (legacy mouse events only). - * @private - * @inner - */ - function releaseMouse( tracker ) { - var delegate = THIS[ tracker.hash ]; - - if ( delegate.capturing ) { - // 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) - $.removeEvent( - window, - "mousemove", - delegate.mousemovecaptured, - true - ); - $.removeEvent( - window, - "mouseup", - delegate.mouseupcaptured, - true - ); - delegate.capturing = false; - } - } - - - /** - * Begin capturing pointer events to the tracked element (pointer event model only). - * @private - * @inner - */ - function capturePointer( tracker ) { + function capturePointer( tracker, isLegacyMouse ) { var delegate = THIS[ tracker.hash ]; delegate.pointerCaptureCount++; @@ -1151,27 +1094,26 @@ // (Note we listen on the capture phase so the captured handlers will get called first) $.addEvent( window, - $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', - delegate.pointerupcaptured, + isLegacyMouse ? 'mouseup' : ($.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp'), + isLegacyMouse ? delegate.mouseupcaptured : delegate.pointerupcaptured, true ); $.addEvent( window, - $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', - delegate.pointermovecaptured, + isLegacyMouse ? 'mousemove' : ($.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove'), + isLegacyMouse ? delegate.mousemovecaptured : delegate.pointermovecaptured, true ); - delegate.capturing = true; } } /** - * Stop capturing pointer events to the tracked element (pointer event model only). + * Stop capturing pointer events to the tracked element. * @private * @inner */ - function releasePointer( tracker ) { + function releasePointer( tracker, isLegacyMouse ) { var delegate = THIS[ tracker.hash ]; delegate.pointerCaptureCount--; @@ -1182,17 +1124,16 @@ // (Note we listen on the capture phase so the captured handlers will get called first) $.removeEvent( window, - $.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove', - delegate.pointermovecaptured, + isLegacyMouse ? 'mousemove' : ($.MouseTracker.unprefixedPointerEvents ? 'pointermove' : 'MSPointerMove'), + isLegacyMouse ? delegate.mousemovecaptured : delegate.pointermovecaptured, true ); $.removeEvent( window, - $.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp', - delegate.pointerupcaptured, + isLegacyMouse ? 'mouseup' : ($.MouseTracker.unprefixedPointerEvents ? 'pointerup' : 'MSPointerUp'), + isLegacyMouse ? delegate.mouseupcaptured : delegate.pointerupcaptured, true ); - delegate.capturing = false; } } @@ -1535,7 +1476,7 @@ if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { $.stopEvent( event ); - captureMouse( tracker ); + capturePointer( tracker, true ); } if ( tracker.clickHandler || tracker.dblClickHandler || tracker.pressHandler || tracker.dragHandler || tracker.dragEndHandler ) { @@ -1583,7 +1524,7 @@ }; if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { - releaseMouse( tracker ); + releasePointer( tracker, true ); } } @@ -1876,7 +1817,7 @@ }; if ( updatePointersDown( tracker, event, [ gPoint ], event.button ) ) { - capturePointer( tracker ); + capturePointer( tracker, false ); $.stopEvent( event ); } @@ -1927,7 +1868,7 @@ }; if ( updatePointersUp( tracker, event, [ gPoint ], event.button ) ) { - releasePointer( tracker ); + releasePointer( tracker, false ); //$.stopEvent( event ); } } From 1d5b059fcc9a0ec23b0f211b05a6fc496010414d Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Wed, 6 Aug 2014 11:26:18 -0700 Subject: [PATCH 08/11] Call Viewport.applyConstraints() on drag-end when flick gesture is enabled --- src/viewer.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index 46d6a527..fca5d6de 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -2388,8 +2388,8 @@ function onCanvasDragEnd( event ) { target.y = center.y; } this.viewport.panTo( target, false ); - this.viewport.applyConstraints(); } + this.viewport.applyConstraints(); } /** * Raised when a mouse or touch drag operation ends on the {@link OpenSeadragon.Viewer#canvas} element. @@ -2417,15 +2417,6 @@ function onCanvasDragEnd( event ) { } function onCanvasRelease( event ) { - var gestureSettings; - - if ( event.insideElementPressed && this.viewport ) { - gestureSettings = this.gestureSettingsByDeviceType( event.pointerType ); - - if ( !gestureSettings.flickEnabled ) { - this.viewport.applyConstraints(); - } - } /** * Raised when the mouse button is released or touch ends on the {@link OpenSeadragon.Viewer#canvas} element. * From 94f7ca3b66a68ab994f69215ab5639c89f27aa2d Mon Sep 17 00:00:00 2001 From: Mark Salsbery Date: Wed, 6 Aug 2014 11:38:43 -0700 Subject: [PATCH 09/11] Changelog update --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 8c4c773c..9e3cff47 100644 --- a/changelog.txt +++ b/changelog.txt @@ -10,6 +10,7 @@ OPENSEADRAGON CHANGELOG * Fix for IIPServer-style urls when using DZI (#413) * Fix memory leak while destroying the viewer (#421) * Added fitBoundsWithConstraints() to the viewport (#423) +* Fixed MouseTracker cross-browser issues with tracking pointers over and out of the tracked element (pull request #448, fix for #152, #404, #420, and #427) 1.1.1: From a672ca978546e81456ff323278aeddc71f9af121 Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Thu, 7 Aug 2014 10:50:38 +0100 Subject: [PATCH 10/11] Fixes incorrect flick direction after image is rotated. --- src/viewer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index 7ba1e7c0..67944456 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -2382,8 +2382,8 @@ function onCanvasDragEnd( event ) { if ( !event.preventDefaultAction && this.viewport ) { gestureSettings = this.gestureSettingsByDeviceType( event.pointerType ); if ( gestureSettings.flickEnabled && event.speed >= gestureSettings.flickMinSpeed ) { - var amplitudeX = gestureSettings.flickMomentum * ( event.speed * Math.cos( event.direction ) ), - amplitudeY = gestureSettings.flickMomentum * ( event.speed * Math.sin( event.direction ) ), + var amplitudeX = gestureSettings.flickMomentum * ( event.speed * Math.cos( event.direction - (Math.PI / 180 * this.viewport.degrees) ) ), + amplitudeY = gestureSettings.flickMomentum * ( event.speed * Math.sin( event.direction - (Math.PI / 180 * this.viewport.degrees) ) ), center = this.viewport.pixelFromPoint( this.viewport.getCenter( true ) ), target = this.viewport.pointFromPixel( new $.Point( center.x - amplitudeX, center.y - amplitudeY ) ); if( !this.panHorizontal ) { From bf75405c39777e6d0c18bbedcfbc7eb16dc93c89 Mon Sep 17 00:00:00 2001 From: Ian Gilman Date: Thu, 7 Aug 2014 10:05:01 -0700 Subject: [PATCH 11/11] Changelog for #452 --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index 9e3cff47..14cd06f2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -11,6 +11,7 @@ OPENSEADRAGON CHANGELOG * Fix memory leak while destroying the viewer (#421) * Added fitBoundsWithConstraints() to the viewport (#423) * Fixed MouseTracker cross-browser issues with tracking pointers over and out of the tracked element (pull request #448, fix for #152, #404, #420, and #427) +* Fixed incorrect flick direction after image is rotated (#452) 1.1.1: