From 23d00c92c141c335969bd7d3ebaa272f78940aa4 Mon Sep 17 00:00:00 2001 From: Mark Salsbery <> Date: Tue, 16 Mar 2021 19:35:22 -0700 Subject: [PATCH 1/3] Added preventDefault option to MouseTracker handlers: scrollHandler, keyDownHandler, keyUpHandler, keyHandler --- changelog.txt | 1 + src/button.js | 6 +- src/mousetracker.js | 158 +++++++++++++++++++++--------------------- src/navigator.js | 20 ++++-- src/referencestrip.js | 42 +++++++---- src/viewer.js | 22 ++++++ 6 files changed, 148 insertions(+), 101 deletions(-) diff --git a/changelog.txt b/changelog.txt index 6cf91f4f..6ddec876 100644 --- a/changelog.txt +++ b/changelog.txt @@ -40,6 +40,7 @@ OPENSEADRAGON CHANGELOG * Fixed preventDefaultAction functionality in viewer events (#1953 @msalsbery) * Added setImageFormatsSupported function (#1954 @pandaxtc) * Added dragToPan to the GestureSettings class, implemented in Viewer (#1956 @msalsbery) +* Added preventDefault option to MouseTracker handlers: scrollHandler, keyDownHandler, keyUpHandler, keyHandler (# @msalsbery) 2.4.2: diff --git a/src/button.js b/src/button.js index 5eaabfc3..7abee6a7 100644 --- a/src/button.js +++ b/src/button.js @@ -360,9 +360,11 @@ $.Button = function( options ) { * @property {?Object} userData - Arbitrary subscriber-defined object. */ _this.raiseEvent( "release", { originalEvent: event.originalEvent } ); - return false; + + event.preventDefault = true; + } else{ + event.preventDefault = false; } - return true; } }); diff --git a/src/mousetracker.js b/src/mousetracker.js index 1b0699f2..abd33fdd 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -707,6 +707,8 @@ * True if the original event is a touch event, otherwise false. Deprecated. Use pointerType and/or originalEvent instead. Touch devices no longer generate scroll event. * @param {Object} event.originalEvent * The original event object. + * @param {Boolean} event.preventDefault + * Set to true to prevent the default user-agent's handling of the wheel event. * @param {Object} event.userData * Arbitrary user-defined object. */ @@ -885,6 +887,8 @@ * True if the meta key was pressed during this event. * @param {Object} event.originalEvent * The original event object. + * @param {Boolean} event.preventDefault + * Set to true to prevent the default user-agent's handling of the keydown event. * @param {Object} event.userData * Arbitrary user-defined object. */ @@ -909,6 +913,8 @@ * True if the meta key was pressed during this event. * @param {Object} event.originalEvent * The original event object. + * @param {Boolean} event.preventDefault + * Set to true to prevent the default user-agent's handling of the keyup event. * @param {Object} event.userData * Arbitrary user-defined object. */ @@ -933,6 +939,8 @@ * True if the meta key was pressed during this event. * @param {Object} event.originalEvent * The original event object. + * @param {Boolean} event.preventDefault + * Set to true to prevent the default user-agent's handling of the keypress event. * @param {Object} event.userData * Arbitrary user-defined object. */ @@ -1772,6 +1780,8 @@ */ function onKeyDown( tracker, event ) { //$.console.log( "keydown %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); + var eventArgs = null; + var eventInfo = { originalEvent: event, eventType: 'keydown', @@ -1781,22 +1791,23 @@ preProcessEvent( tracker, eventInfo ); if ( tracker.keyDownHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { - tracker.keyDownHandler( - { - eventSource: tracker, - keyCode: event.keyCode ? event.keyCode : event.charCode, - ctrl: event.ctrlKey, - shift: event.shiftKey, - alt: event.altKey, - meta: event.metaKey, - originalEvent: event, - userData: tracker.userData - } - ); + eventArgs = { + eventSource: tracker, + keyCode: event.keyCode ? event.keyCode : event.charCode, + ctrl: event.ctrlKey, + shift: event.shiftKey, + alt: event.altKey, + meta: event.metaKey, + originalEvent: event, + preventDefault: eventInfo.preventDefault || eventInfo.defaultPrevented, + userData: tracker.userData + }; + + tracker.keyDownHandler( eventArgs ); } - if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { - $.cancelEvent( event ); + if ( ( eventArgs && eventArgs.preventDefault ) || ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) ) { + $.cancelEvent( event ); } if ( eventInfo.stopPropagation ) { $.stopEvent( event ); @@ -1811,6 +1822,8 @@ function onKeyUp( tracker, event ) { //$.console.log( "keyup %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); + var eventArgs = null; + var eventInfo = { originalEvent: event, eventType: 'keyup', @@ -1820,21 +1833,22 @@ preProcessEvent( tracker, eventInfo ); if ( tracker.keyUpHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { - tracker.keyUpHandler( - { - eventSource: tracker, - keyCode: event.keyCode ? event.keyCode : event.charCode, - ctrl: event.ctrlKey, - shift: event.shiftKey, - alt: event.altKey, - meta: event.metaKey, - originalEvent: event, - userData: tracker.userData - } - ); + eventArgs = { + eventSource: tracker, + keyCode: event.keyCode ? event.keyCode : event.charCode, + ctrl: event.ctrlKey, + shift: event.shiftKey, + alt: event.altKey, + meta: event.metaKey, + originalEvent: event, + preventDefault: eventInfo.preventDefault || eventInfo.defaultPrevented, + userData: tracker.userData + }; + + tracker.keyUpHandler( eventArgs ); } - if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { + if ( ( eventArgs && eventArgs.preventDefault ) || ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) ) { $.cancelEvent( event ); } if ( eventInfo.stopPropagation ) { @@ -1850,6 +1864,8 @@ function onKeyPress( tracker, event ) { //$.console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); + var eventArgs = null; + var eventInfo = { originalEvent: event, eventType: 'keypress', @@ -1859,21 +1875,22 @@ preProcessEvent( tracker, eventInfo ); if ( tracker.keyHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { - tracker.keyHandler( - { - eventSource: tracker, - keyCode: event.keyCode ? event.keyCode : event.charCode, - ctrl: event.ctrlKey, - shift: event.shiftKey, - alt: event.altKey, - meta: event.metaKey, - originalEvent: event, - userData: tracker.userData - } - ); + eventArgs = { + eventSource: tracker, + keyCode: event.keyCode ? event.keyCode : event.charCode, + ctrl: event.ctrlKey, + shift: event.shiftKey, + alt: event.altKey, + meta: event.metaKey, + originalEvent: event, + preventDefault: eventInfo.preventDefault || eventInfo.defaultPrevented, + userData: tracker.userData + }; + + tracker.keyHandler( eventArgs ); } - if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { + if ( ( eventArgs && eventArgs.preventDefault ) || ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) ) { $.cancelEvent( event ); } if ( eventInfo.stopPropagation ) { @@ -2035,6 +2052,8 @@ var nDelta = 0, eventInfo; + var eventArgs = null; + // The nDelta variable is gated to provide smooth z-index scrolling // since the mouse wheel allows for substantial deltas meant for rapid // y-index scrolling. @@ -2051,27 +2070,28 @@ preProcessEvent( tracker, eventInfo ); if ( tracker.scrollHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { - eventInfo.preventDefault = true; + eventArgs = { + eventSource: tracker, + pointerType: 'mouse', + position: getMouseRelative( event, tracker.element ), + scroll: nDelta, + shift: event.shiftKey, + isTouchEvent: false, + originalEvent: originalEvent, + preventDefault: eventInfo.preventDefault || eventInfo.defaultPrevented, + userData: tracker.userData + }; - tracker.scrollHandler( - { - eventSource: tracker, - pointerType: 'mouse', - position: getMouseRelative( event, tracker.element ), - scroll: nDelta, - shift: event.shiftKey, - isTouchEvent: false, - originalEvent: originalEvent, - userData: tracker.userData - } - ); + + tracker.scrollHandler( eventArgs ); } if ( eventInfo.stopPropagation ) { $.stopEvent( originalEvent ); } - if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { - $.cancelEvent( originalEvent ); + //if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { + if ( ( eventArgs && eventArgs.preventDefault ) || ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) ) { + $.cancelEvent( originalEvent ); } } @@ -2811,9 +2831,12 @@ case 'pointerover': case 'pointerout': case 'contextmenu': + case 'keydown': + case 'keyup': + case 'keypress': eventInfo.isStopable = true; eventInfo.isCancelable = true; - eventInfo.preventDefault = false; + eventInfo.preventDefault = false; // onContextMenu(), onKeyDown(), onKeyUp(), onKeyPress() may set true eventInfo.preventGesture = false; eventInfo.stopPropagation = false; break; @@ -2834,7 +2857,7 @@ case 'wheel': eventInfo.isStopable = true; eventInfo.isCancelable = true; - eventInfo.preventDefault = false; // handleWheelEvent() may set true (tracker.hasScrollHandler) + eventInfo.preventDefault = false; // handleWheelEvent() may set true eventInfo.preventGesture = !tracker.hasScrollHandler; eventInfo.stopPropagation = false; break; @@ -2861,27 +2884,6 @@ eventInfo.preventGesture = false; eventInfo.stopPropagation = false; break; - case 'keydown': - eventInfo.isStopable = true; - eventInfo.isCancelable = true; - eventInfo.preventDefault = !!tracker.keyDownHandler; - eventInfo.preventGesture = false; - eventInfo.stopPropagation = false; - break; - case 'keyup': - eventInfo.isStopable = true; - eventInfo.isCancelable = true; - eventInfo.preventDefault = !!tracker.keyUpHandler; - eventInfo.preventGesture = false; - eventInfo.stopPropagation = false; - break; - case 'keypress': - eventInfo.isStopable = true; - eventInfo.isCancelable = true; - eventInfo.preventDefault = !!tracker.keyHandler; - eventInfo.preventGesture = false; - eventInfo.stopPropagation = false; - break; case 'focus': case 'blur': case 'pointerenter': diff --git a/src/navigator.js b/src/navigator.js index d088c098..9b64d2bd 100644 --- a/src/navigator.js +++ b/src/navigator.js @@ -593,6 +593,15 @@ function onCanvasRelease( event ) { * @function */ function onCanvasScroll( event ) { + var eventArgs = { + tracker: event.eventSource, + position: event.position, + scroll: event.scroll, + shift: event.shift, + originalEvent: event.originalEvent, + preventDefault: event.preventDefault + }; + /** * Raised when a scroll event occurs on the {@link OpenSeadragon.Viewer#navigator} element (mouse wheel, touch pinch, etc.). * @@ -605,15 +614,12 @@ function onCanvasScroll( event ) { * @property {Number} scroll - The scroll delta for the event. * @property {Boolean} shift - True if the shift key was pressed during this event. * @property {Object} originalEvent - The original DOM event. + * @property {Boolean} preventDefault - Set to true to prevent the default user-agent's handling of the wheel event. * @property {?Object} userData - Arbitrary subscriber-defined object. */ - this.viewer.raiseEvent( 'navigator-scroll', { - tracker: event.eventSource, - position: event.position, - scroll: event.scroll, - shift: event.shift, - originalEvent: event.originalEvent - }); + this.viewer.raiseEvent( 'navigator-scroll', eventArgs ); + + event.preventDefault = eventArgs.preventDefault; } /** diff --git a/src/referencestrip.js b/src/referencestrip.js index 738a55ab..1d4b7104 100644 --- a/src/referencestrip.js +++ b/src/referencestrip.js @@ -400,6 +400,8 @@ function onStripScroll( event ) { } } } + + event.preventDefault = true; } } @@ -528,22 +530,27 @@ function onKeyDown( event ) { switch ( event.keyCode ) { case 38: //up arrow onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } ); - return false; + event.preventDefault = true; + break; case 40: //down arrow onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } ); - return false; + event.preventDefault = true; + break; case 37: //left arrow onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } ); - return false; + event.preventDefault = true; + break; case 39: //right arrow onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } ); - return false; + event.preventDefault = true; + break; default: //console.log( 'navigator keycode %s', event.keyCode ); - return true; + event.preventDefault = false; + break; } } else { - return true; + event.preventDefault = false; } } @@ -560,31 +567,38 @@ function onKeyPress( event ) { switch ( event.keyCode ) { case 61: //=|+ onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } ); - return false; + event.preventDefault = true; + break; case 45: //-|_ onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } ); - return false; + event.preventDefault = true; + break; case 48: //0|) case 119: //w case 87: //W onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } ); - return false; + event.preventDefault = true; + break; case 115: //s case 83: //S onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } ); - return false; + event.preventDefault = true; + break; case 97: //a onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: -1, shift: null } ); - return false; + event.preventDefault = true; + break; case 100: //d onStripScroll.call( this, { eventSource: this.tracker, position: null, scroll: 1, shift: null } ); - return false; + event.preventDefault = true; + break; default: //console.log( 'navigator keycode %s', event.keyCode ); - return true; + event.preventDefault = false; + break; } } else { - return true; + event.preventDefault = false; } } diff --git a/src/viewer.js b/src/viewer.js index c22d3f34..4c0465e3 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -2606,6 +2606,7 @@ function onCanvasKeyDown( event ) { } this.viewport.applyConstraints(); } + event.preventDefault = true; break; case 40://down arrow if (!canvasKeyDownEventArgs.preventVerticalPan) { @@ -2616,23 +2617,29 @@ function onCanvasKeyDown( event ) { } this.viewport.applyConstraints(); } + event.preventDefault = true; break; case 37://left arrow if (!canvasKeyDownEventArgs.preventHorizontalPan) { this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-this.pixelsPerArrowPress, 0))); this.viewport.applyConstraints(); } + event.preventDefault = true; break; case 39://right arrow if (!canvasKeyDownEventArgs.preventHorizontalPan) { this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(this.pixelsPerArrowPress, 0))); this.viewport.applyConstraints(); } + event.preventDefault = true; break; default: //console.log( 'navigator keycode %s', event.keyCode ); + event.preventDefault = false; break; } + } else { + event.preventDefault = false; } } function onCanvasKeyPress( event ) { @@ -2652,14 +2659,17 @@ function onCanvasKeyPress( event ) { case 61://=|+ this.viewport.zoomBy(1.1); this.viewport.applyConstraints(); + event.preventDefault = true; break; case 45://-|_ this.viewport.zoomBy(0.9); this.viewport.applyConstraints(); + event.preventDefault = true; break; case 48://0|) this.viewport.goHome(); this.viewport.applyConstraints(); + event.preventDefault = true; break; case 119://w case 87://W @@ -2671,6 +2681,7 @@ function onCanvasKeyPress( event ) { } this.viewport.applyConstraints(); } + event.preventDefault = true; break; case 115://s case 83://S @@ -2682,18 +2693,21 @@ function onCanvasKeyPress( event ) { } this.viewport.applyConstraints(); } + event.preventDefault = true; break; case 97://a if (!canvasKeyPressEventArgs.preventHorizontalPan) { this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-40, 0))); this.viewport.applyConstraints(); } + event.preventDefault = true; break; case 100://d if (!canvasKeyPressEventArgs.preventHorizontalPan) { this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(40, 0))); this.viewport.applyConstraints(); } + event.preventDefault = true; break; case 114: //r - clockwise rotation if(this.viewport.flipped){ @@ -2702,6 +2716,7 @@ function onCanvasKeyPress( event ) { this.viewport.setRotation($.positiveModulo(this.viewport.degrees + this.rotationIncrement, 360)); } this.viewport.applyConstraints(); + event.preventDefault = true; break; case 82: //R - counterclockwise rotation if(this.viewport.flipped){ @@ -2710,14 +2725,19 @@ function onCanvasKeyPress( event ) { this.viewport.setRotation($.positiveModulo(this.viewport.degrees - this.rotationIncrement, 360)); } this.viewport.applyConstraints(); + event.preventDefault = true; break; case 102: //f this.viewport.toggleFlip(); + event.preventDefault = true; break; default: // console.log( 'navigator keycode %s', event.keyCode ); + event.preventDefault = false; break; } + } else { + event.preventDefault = false; } } @@ -3240,6 +3260,8 @@ function onCanvasScroll( event ) { } } } + + event.preventDefault = true; } function onContainerEnter( event ) { From 870d9df77960e05ed853b3779023ff954f66c642 Mon Sep 17 00:00:00 2001 From: Mark Salsbery <> Date: Tue, 16 Mar 2021 19:47:08 -0700 Subject: [PATCH 2/3] Code cleanup, better scrollHandler handling in Viewer --- src/mousetracker.js | 1 - src/viewer.js | 10 +++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mousetracker.js b/src/mousetracker.js index abd33fdd..f4214a27 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -2089,7 +2089,6 @@ if ( eventInfo.stopPropagation ) { $.stopEvent( originalEvent ); } - //if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { if ( ( eventArgs && eventArgs.preventDefault ) || ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) ) { $.cancelEvent( originalEvent ); } diff --git a/src/viewer.js b/src/viewer.js index 4c0465e3..29b2054a 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -3224,7 +3224,8 @@ function onCanvasScroll( event ) { scroll: event.scroll, shift: event.shift, originalEvent: event.originalEvent, - preventDefaultAction: false + preventDefaultAction: false, + preventDefault: true }; /** @@ -3240,6 +3241,7 @@ function onCanvasScroll( event ) { * @property {Boolean} shift - True if the shift key was pressed during this event. * @property {Object} originalEvent - The original DOM event. * @property {Boolean} preventDefaultAction - Set to true to prevent default scroll to zoom behaviour. Default: false. + * @property {Boolean} preventDefault - Set to true to prevent the default user-agent's handling of the wheel event. Default: true. * @property {?Object} userData - Arbitrary subscriber-defined object. */ this.raiseEvent('canvas-scroll', canvasScrollEventArgs ); @@ -3259,9 +3261,11 @@ function onCanvasScroll( event ) { this.viewport.applyConstraints(); } } - } - event.preventDefault = true; + event.preventDefault = canvasScrollEventArgs.preventDefault; + } else { + event.preventDefault = true; + } } function onContainerEnter( event ) { From 8c29f705e65ccab308cf1cc7b29b98ff2ca5062d Mon Sep 17 00:00:00 2001 From: Mark Salsbery <> Date: Tue, 16 Mar 2021 19:48:08 -0700 Subject: [PATCH 3/3] changelog update --- changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.txt b/changelog.txt index 6ddec876..3e4c2d66 100644 --- a/changelog.txt +++ b/changelog.txt @@ -40,7 +40,7 @@ OPENSEADRAGON CHANGELOG * Fixed preventDefaultAction functionality in viewer events (#1953 @msalsbery) * Added setImageFormatsSupported function (#1954 @pandaxtc) * Added dragToPan to the GestureSettings class, implemented in Viewer (#1956 @msalsbery) -* Added preventDefault option to MouseTracker handlers: scrollHandler, keyDownHandler, keyUpHandler, keyHandler (# @msalsbery) +* Added preventDefault option to MouseTracker handlers: scrollHandler, keyDownHandler, keyUpHandler, keyHandler (#1957 @msalsbery) 2.4.2: