diff --git a/lib/jsdom/living/events/Event-impl.js b/lib/jsdom/living/events/Event-impl.js index 0a4867f759..89b8e61da4 100644 --- a/lib/jsdom/living/events/Event-impl.js +++ b/lib/jsdom/living/events/Event-impl.js @@ -22,7 +22,7 @@ class EventImpl { } } - this.target = null; + this._target = null; this.currentTarget = null; this.eventPhase = 0; @@ -46,6 +46,14 @@ class EventImpl { } } + get target() { + return this._target; + } + + set target(target) { + this._target = target; + } + get srcElement() { return this.target; } diff --git a/lib/jsdom/living/events/MouseEvent-impl.js b/lib/jsdom/living/events/MouseEvent-impl.js index 51df52be26..d96e6d03aa 100644 --- a/lib/jsdom/living/events/MouseEvent-impl.js +++ b/lib/jsdom/living/events/MouseEvent-impl.js @@ -16,41 +16,50 @@ class MouseEventImpl extends UIEventImpl { } get pageX() { if (this._dispatchFlag) { - return this._initialContainingBlockRelativeX; + return this._pageX; } const offset = wrapperForImpl(this.view)?.scrollX || 0; return offset + this.clientX; } get pageY() { if (this._dispatchFlag) { - return this._initialContainingBlockRelativeY; + return this._pageY; } const offset = wrapperForImpl(this.view)?.scrollY || 0; return offset + this.clientY; } get offsetX() { if (this._dispatchFlag) { - return this._paddingEdgeRelativeX; + return this._offsetX; } return this.pageX; } get offsetY() { if (this._dispatchFlag) { - return this._paddingEdgeRelativeY; + return this._offsetY; } return this.pageY; } - constructor(globalObject, args, privateData) { - super(globalObject, args, privateData); + /** @override */ + get target() { + return super.target; + } - // We cache this during init so that we have a stable value during dispatch - const { scrollX = 0, scrollY = 0 } = wrapperForImpl(this.view) ?? {}; - this._initialContainingBlockRelativeX = this.clientX + scrollX; - this._initialContainingBlockRelativeY = this.clientY + scrollY; - // TODO: support non-zero values somehow if/when jsdom adds layout support - this._paddingEdgeRelativeX = 0; - this._paddingEdgeRelativeY = 0; + /** + * @override + * calculate the event position when the target is set so that it's stable during dispatch + */ + set target(target) { + super.target = target; + if (target) { + const { scrollX = 0, scrollY = 0 } = wrapperForImpl(this.view) ?? {}; + this._pageX = this.clientX + scrollX; + this._pageY = this.clientY + scrollY; + const domRect = target.getBoundingClientRect?.() ?? { x: 0, y: 0 }; + this._offsetX = this.clientX - domRect.x; + this._offsetY = this.clientY - domRect.y; + } } initMouseEvent( diff --git a/test/web-platform-tests/to-upstream/html/editing/activation/click-event-properties-dontupstream.html b/test/web-platform-tests/to-upstream/html/editing/activation/click-event-properties-dontupstream.html new file mode 100644 index 0000000000..b092348dc1 --- /dev/null +++ b/test/web-platform-tests/to-upstream/html/editing/activation/click-event-properties-dontupstream.html @@ -0,0 +1,55 @@ + + +