diff --git a/changelog.txt b/changelog.txt index 3378279e..ab324cfb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,7 +3,7 @@ OPENSEADRAGON CHANGELOG 2.5.0: (In progress) -* BREAKING CHANGE: Dropped support for older browsers (IE < 11) (#1949 @msalsbery) +* BREAKING CHANGE: Dropped support for older browsers (IE < 11) (#1872 #1949 #1951 @msalsbery, #1950 @rmontroy) * BREAKING CHANGE: Removed deprecated OpenSeadragon.getEvent function (#1949 @msalsbery) * DEPRECATION: MouseTracker exitHandler deprecated for name change to leaveHandler for consistency with DOM event names (#1872 @msalsbery) * Now when "simple image" tile sources are removed from the viewer, they free the memory used by the pyramid they create (#1789 @TakumaKira) @@ -34,8 +34,9 @@ OPENSEADRAGON CHANGELOG * MouseTracker: added contextMenuHandler option for handling contextmenu events (#1872 @msalsbery) * Viewer: added a canvas-contextmenu event (#1872 @msalsbery) * Added additional documentation for the zoomPerSecond viewer option (#1872 @msalsbery) -* MouseTracker: Per #1863, dropped support for Internet Explorer < 11 (#1872 @msalsbery) (#1950 @rmontroy) * Fixed simulated drag events in navigator tests (#1949 @msalsbery) +* Added preventDefault option to MouseTracker.contextMenuHandler and Viewer 'canvas-contextmenu' event args (#1951 @msalsbery) +* MouseTracker: Added preProcessEventHandler for keydown, keyup, keypress, focus, blur Events (#1951 @msalsbery) * Fixed preventDefaultAction functionality in viewer events (#1953 @msalsbery) 2.4.2: diff --git a/src/imagetilesource.js b/src/imagetilesource.js index da1c201b..25f67988 100644 --- a/src/imagetilesource.js +++ b/src/imagetilesource.js @@ -114,9 +114,8 @@ } $.addEvent(image, 'load', function () { - /* IE8 fix since it has no naturalWidth and naturalHeight */ - _this.width = Object.prototype.hasOwnProperty.call(image, 'naturalWidth') ? image.naturalWidth : image.width; - _this.height = Object.prototype.hasOwnProperty.call(image, 'naturalHeight') ? image.naturalHeight : image.height; + _this.width = image.naturalWidth; + _this.height = image.naturalHeight; _this.aspectRatio = _this.width / _this.height; _this.dimensions = new $.Point(_this.width, _this.height); _this._tileWidth = _this.width; @@ -210,9 +209,8 @@ _buildLevels: function () { var levels = [{ url: this._image.src, - /* IE8 fix since it has no naturalWidth and naturalHeight */ - width: Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width, - height: Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.height + width: this._image.naturalWidth, + height: this._image.naturalHeight }]; if (!this.buildPyramid || !$.supportsCanvas || !this.useCanvas) { @@ -221,9 +219,8 @@ return levels; } - /* IE8 fix since it has no naturalWidth and naturalHeight */ - var currentWidth = Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width; - var currentHeight = Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.height; + var currentWidth = this._image.naturalWidth; + var currentHeight = this._image.naturalHeight; var bigCanvas = document.createElement("canvas"); diff --git a/src/mousetracker.js b/src/mousetracker.js index 04796f28..1b0699f2 100644 --- a/src/mousetracker.js +++ b/src/mousetracker.js @@ -280,7 +280,6 @@ this.dragHandler || this.dragEndHandler || this.pinchHandler ); this.hasScrollHandler = !!this.scrollHandler; - this.hasContextMenuHandler = !!this.contextMenuHandler; if (this.exitHandler) { $.console.error("MouseTracker.exitHandler is deprecated. Use MouseTracker.leaveHandler instead."); @@ -402,6 +401,8 @@ * The position of the event relative to the tracked element. * @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 contextmenu event. * @param {Object} event.userData * Arbitrary user-defined object. */ @@ -1170,7 +1171,7 @@ * @property {Number} eventPhase * 0 == NONE, 1 == CAPTURING_PHASE, 2 == AT_TARGET, 3 == BUBBLING_PHASE. * @property {String} eventType - * "contextmenu", "gotpointercapture", "lostpointercapture", "pointerenter", "pointerleave", "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel", "wheel", "click", "dblclick". + * "keydown", "keyup", "keypress", "focus", "blur", "contextmenu", "gotpointercapture", "lostpointercapture", "pointerenter", "pointerleave", "pointerover", "pointerout", "pointerdown", "pointerup", "pointermove", "pointercancel", "wheel", "click", "dblclick". * @property {String} pointerType * "mouse", "touch", "pen", etc. * @property {Boolean} isEmulated @@ -1771,9 +1772,16 @@ */ function onKeyDown( tracker, event ) { //$.console.log( "keydown %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); - var propagate; - if ( tracker.keyDownHandler ) { - propagate = tracker.keyDownHandler( + var eventInfo = { + originalEvent: event, + eventType: 'keydown', + pointerType: '', + isEmulated: false + }; + preProcessEvent( tracker, eventInfo ); + + if ( tracker.keyDownHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { + tracker.keyDownHandler( { eventSource: tracker, keyCode: event.keyCode ? event.keyCode : event.charCode, @@ -1785,9 +1793,13 @@ userData: tracker.userData } ); - if ( !propagate ) { - $.cancelEvent( event ); - } + } + + if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { + $.cancelEvent( event ); + } + if ( eventInfo.stopPropagation ) { + $.stopEvent( event ); } } @@ -1798,9 +1810,17 @@ */ function onKeyUp( tracker, event ) { //$.console.log( "keyup %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); - var propagate; - if ( tracker.keyUpHandler ) { - propagate = tracker.keyUpHandler( + + var eventInfo = { + originalEvent: event, + eventType: 'keyup', + pointerType: '', + isEmulated: false + }; + preProcessEvent( tracker, eventInfo ); + + if ( tracker.keyUpHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { + tracker.keyUpHandler( { eventSource: tracker, keyCode: event.keyCode ? event.keyCode : event.charCode, @@ -1812,9 +1832,13 @@ userData: tracker.userData } ); - if ( !propagate ) { - $.cancelEvent( event ); - } + } + + if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { + $.cancelEvent( event ); + } + if ( eventInfo.stopPropagation ) { + $.stopEvent( event ); } } @@ -1825,9 +1849,17 @@ */ function onKeyPress( tracker, event ) { //$.console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); - var propagate; - if ( tracker.keyHandler ) { - propagate = tracker.keyHandler( + + var eventInfo = { + originalEvent: event, + eventType: 'keypress', + pointerType: '', + isEmulated: false + }; + preProcessEvent( tracker, eventInfo ); + + if ( tracker.keyHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { + tracker.keyHandler( { eventSource: tracker, keyCode: event.keyCode ? event.keyCode : event.charCode, @@ -1839,9 +1871,13 @@ userData: tracker.userData } ); - if ( !propagate ) { - $.cancelEvent( event ); - } + } + + if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { + $.cancelEvent( event ); + } + if ( eventInfo.stopPropagation ) { + $.stopEvent( event ); } } @@ -1852,18 +1888,26 @@ */ function onFocus( tracker, event ) { //console.log( "focus %s", event ); - var propagate; - if ( tracker.focusHandler ) { - propagate = tracker.focusHandler( + + // focus doesn't bubble and is not cancelable, but we call + // preProcessEvent() so it's dispatched to preProcessEventHandler + // if necessary + var eventInfo = { + originalEvent: event, + eventType: 'focus', + pointerType: '', + isEmulated: false + }; + preProcessEvent( tracker, eventInfo ); + + if ( tracker.focusHandler && !eventInfo.preventGesture ) { + tracker.focusHandler( { eventSource: tracker, originalEvent: event, userData: tracker.userData } ); - if ( propagate === false ) { - $.cancelEvent( event ); - } } } @@ -1874,18 +1918,26 @@ */ function onBlur( tracker, event ) { //console.log( "blur %s", event ); - var propagate; - if ( tracker.blurHandler ) { - propagate = tracker.blurHandler( + + // blur doesn't bubble and is not cancelable, but we call + // preProcessEvent() so it's dispatched to preProcessEventHandler + // if necessary + var eventInfo = { + originalEvent: event, + eventType: 'blur', + pointerType: '', + isEmulated: false + }; + preProcessEvent( tracker, eventInfo ); + + if ( tracker.blurHandler && !eventInfo.preventGesture ) { + tracker.blurHandler( { eventSource: tracker, originalEvent: event, userData: tracker.userData } ); - if ( propagate === false ) { - $.cancelEvent( event ); - } } } @@ -1897,6 +1949,8 @@ function onContextMenu( tracker, event ) { //$.console.log('contextmenu ' + (tracker.userData ? tracker.userData.toString() : '') + ' ' + (event.target === tracker.element ? 'tracker.element' : '')); + var eventArgs = null; + var eventInfo = { originalEvent: event, eventType: 'contextmenu', @@ -1907,17 +1961,18 @@ // ContextMenu if ( tracker.contextMenuHandler && !eventInfo.preventGesture && !eventInfo.defaultPrevented ) { - tracker.contextMenuHandler( - { - eventSource: tracker, - position: getPointRelativeToAbsolute( getMouseAbsolute( event ), tracker.element ), - originalEvent: eventInfo.originalEvent, - userData: tracker.userData - } - ); + eventArgs = { + eventSource: tracker, + position: getPointRelativeToAbsolute( getMouseAbsolute( event ), tracker.element ), + originalEvent: eventInfo.originalEvent, + preventDefault: eventInfo.preventDefault || eventInfo.defaultPrevented, + userData: tracker.userData + }; + + tracker.contextMenuHandler( eventArgs ); } - if ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) { + if ( ( eventArgs && eventArgs.preventDefault ) || ( eventInfo.preventDefault && !eventInfo.defaultPrevented ) ) { $.cancelEvent( event ); } if ( eventInfo.stopPropagation ) { @@ -2755,6 +2810,7 @@ break; case 'pointerover': case 'pointerout': + case 'contextmenu': eventInfo.isStopable = true; eventInfo.isCancelable = true; eventInfo.preventDefault = false; @@ -2764,7 +2820,7 @@ case 'pointerdown': eventInfo.isStopable = true; eventInfo.isCancelable = true; - eventInfo.preventDefault = false;//tracker.hasGestureHandlers; + eventInfo.preventDefault = false; // updatePointerDown() may set true (tracker.hasGestureHandlers) eventInfo.preventGesture = !tracker.hasGestureHandlers; eventInfo.stopPropagation = false; break; @@ -2778,7 +2834,7 @@ case 'wheel': eventInfo.isStopable = true; eventInfo.isCancelable = true; - eventInfo.preventDefault = false;//tracker.hasScrollHandler; + eventInfo.preventDefault = false; // handleWheelEvent() may set true (tracker.hasScrollHandler) eventInfo.preventGesture = !tracker.hasScrollHandler; eventInfo.stopPropagation = false; break; @@ -2805,13 +2861,29 @@ eventInfo.preventGesture = false; eventInfo.stopPropagation = false; break; - case 'contextmenu': + case 'keydown': eventInfo.isStopable = true; eventInfo.isCancelable = true; - eventInfo.preventDefault = false;//tracker.hasContextMenuHandler; - eventInfo.preventGesture = true;//!tracker.hasContextMenuHandler; + 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': case 'pointerleave': default: diff --git a/src/viewer.js b/src/viewer.js index 42d51359..6e9c65b1 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -2546,6 +2546,13 @@ function onBlur(){ } function onCanvasContextMenu( event ) { + var eventArgs = { + tracker: event.eventSource, + position: event.position, + originalEvent: event.originalEvent, + preventDefault: event.preventDefault + }; + /** * Raised when a contextmenu event occurs in the {@link OpenSeadragon.Viewer#canvas} element. * @@ -2556,13 +2563,12 @@ function onCanvasContextMenu( event ) { * @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event. * @property {OpenSeadragon.Point} position - The position of the event relative to the tracked element. * @property {Object} originalEvent - The original DOM event. + * @property {Boolean} preventDefault - Set to true to prevent the default user-agent's handling of the contextmenu event. * @property {?Object} userData - Arbitrary subscriber-defined object. */ - this.raiseEvent( 'canvas-contextmenu', { - tracker: event.eventSource, - position: event.position, - originalEvent: event.originalEvent - }); + this.raiseEvent( 'canvas-contextmenu', eventArgs ); + + event.preventDefault = eventArgs.preventDefault; } function onCanvasKeyDown( event ) {