diff --git a/src/ol/MapBrowserEvent.js b/src/ol/MapBrowserEvent.js index 9265ebc708..90b502b9b8 100644 --- a/src/ol/MapBrowserEvent.js +++ b/src/ol/MapBrowserEvent.js @@ -7,7 +7,7 @@ import MapEvent from './MapEvent.js'; * @classdesc * Events emitted as map browser events are instances of this type. * See {@link module:ol/PluggableMap~PluggableMap} for which events trigger a map browser event. - * @template {UIEvent} EVENT + * @template {UIEvent|import("./MapBrowserEventHandler").PointerEventData} EVENT */ class MapBrowserEvent extends MapEvent { /** @@ -88,7 +88,9 @@ class MapBrowserEvent extends MapEvent { */ preventDefault() { super.preventDefault(); - this.originalEvent.preventDefault(); + if ('preventDefault' in this.originalEvent) { + /** @type {UIEvent} */ (this.originalEvent).preventDefault(); + } } /** @@ -98,7 +100,9 @@ class MapBrowserEvent extends MapEvent { */ stopPropagation() { super.stopPropagation(); - this.originalEvent.stopPropagation(); + if ('stopPropagation' in this.originalEvent) { + /** @type {UIEvent} */ (this.originalEvent).stopPropagation(); + } } } diff --git a/src/ol/MapBrowserEventHandler.js b/src/ol/MapBrowserEventHandler.js index a778874ec9..c8dcdcd2bb 100644 --- a/src/ol/MapBrowserEventHandler.js +++ b/src/ol/MapBrowserEventHandler.js @@ -2,15 +2,23 @@ * @module ol/MapBrowserEventHandler */ -import EventTarget from './events/Target.js'; import EventType from './events/EventType.js'; import MapBrowserEvent from './MapBrowserEvent.js'; import MapBrowserEventType from './MapBrowserEventType.js'; import PointerEventType from './pointer/EventType.js'; +import Target from './events/Target.js'; import {DEVICE_PIXEL_RATIO, PASSIVE_EVENT_LISTENERS} from './has.js'; import {listen, unlistenByKey} from './events.js'; -class MapBrowserEventHandler extends EventTarget { +/** + * @typedef {Object} PointerEventData + * @property {string} type + * @property {number} clientX + * @property {number} clientY + * @property {EventTarget} target + */ + +class MapBrowserEventHandler extends Target { /** * @param {import("./PluggableMap.js").default} map The map with the viewport to listen to events on. * @param {number} [moveTolerance] The minimal distance the pointer must travel to trigger a move. @@ -60,7 +68,7 @@ class MapBrowserEventHandler extends EventTarget { /** * The most recent "down" type event (or null if none have occurred). * Set on pointerdown. - * @type {PointerEvent} + * @type {PointerEventData} * @private */ this.down_ = null; @@ -122,7 +130,7 @@ class MapBrowserEventHandler extends EventTarget { } /** - * @param {PointerEvent} pointerEvent Pointer + * @param {PointerEventData} pointerEvent Pointer * event. * @private */ @@ -244,7 +252,12 @@ class MapBrowserEventHandler extends EventTarget { ); this.dispatchEvent(newEvent); - this.down_ = pointerEvent; + this.down_ = { + type: pointerEvent.type, + clientX: pointerEvent.clientX, + clientY: pointerEvent.clientY, + target: pointerEvent.target, + }; if (this.dragListenerKeys_.length === 0) { const doc = this.map_.getOwnerDocument(); diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 7f53e2cd7b..1ca470e823 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -682,7 +682,7 @@ class PluggableMap extends BaseObject { /** * Returns the map pixel position for a browser event relative to the viewport. - * @param {UIEvent} event Event. + * @param {UIEvent|import("./MapBrowserEventHandler").PointerEventData} event Event. * @return {import("./pixel.js").Pixel} Pixel. * @api */ @@ -944,9 +944,8 @@ class PluggableMap extends BaseObject { * @return {!Document} The document where the map is displayed. */ getOwnerDocument() { - return this.getTargetElement() - ? this.getTargetElement().ownerDocument - : document; + const targetElement = this.getTargetElement(); + return targetElement ? targetElement.ownerDocument : document; } /** @@ -992,17 +991,7 @@ class PluggableMap extends BaseObject { eventType === EventType.WHEEL || eventType === EventType.KEYDOWN ) { - const doc = this.getOwnerDocument(); - const rootNode = this.viewport_.getRootNode - ? this.viewport_.getRootNode() - : doc; - const target = - 'host' in rootNode // ShadowRoot - ? /** @type {ShadowRoot} */ (rootNode).elementFromPoint( - originalEvent.clientX, - originalEvent.clientY - ) - : /** @type {Node} */ (originalEvent.target); + const target = /** @type {Node} */ (originalEvent.target); if ( // Abort if the target is a child of the container for elements whose events are not meant // to be handled by map interactions. @@ -1011,7 +1000,7 @@ class PluggableMap extends BaseObject { // It's possible for the target to no longer be in the page if it has been removed in an // event listener, this might happen in a Control that recreates it's content based on // user interaction either manually or via a render in something like https://reactjs.org/ - !(rootNode === doc ? doc.documentElement : rootNode).contains(target) + !this.getOwnerDocument().contains(target) ) { return; } diff --git a/test/spec/ol/MapBrowserEventHandler.test.js b/test/spec/ol/MapBrowserEventHandler.test.js index c6bfc07959..9c41725694 100644 --- a/test/spec/ol/MapBrowserEventHandler.test.js +++ b/test/spec/ol/MapBrowserEventHandler.test.js @@ -94,10 +94,16 @@ describe('ol/MapBrowserEventHandler', function () { expect(handler.down_).to.be(null); }); - it('is an event after handlePointerDown_ has been called', function () { + it('is properly set after handlePointerDown_ has been called', function () { const event = new OlEvent('pointerdown'); + event.clientX = 42; + event.clientY = 666; + event.target = 'foo'; handler.handlePointerDown_(event); - expect(handler.down_).to.be(event); + expect(handler.down_.type).to.be('pointerdown'); + expect(handler.down_.clientX).to.be(42); + expect(handler.down_.clientY).to.be(666); + expect(handler.down_.target).to.be('foo'); }); });