From 966137ca49a24c53e392ca4b06455317f17a27ab Mon Sep 17 00:00:00 2001 From: Pathan Aseef Khan Date: Fri, 31 Oct 2025 15:10:26 -0400 Subject: [PATCH 1/2] fix: clamp logic to not allow negative positions to avoid runaway width/height calculations --- packages/dockview-core/src/overlay/overlay.ts | 82 ++++++++++--------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/packages/dockview-core/src/overlay/overlay.ts b/packages/dockview-core/src/overlay/overlay.ts index 03ecc2f17..26eb70aef 100644 --- a/packages/dockview-core/src/overlay/overlay.ts +++ b/packages/dockview-core/src/overlay/overlay.ts @@ -3,11 +3,7 @@ import { quasiDefaultPrevented, toggleClass, } from '../dom'; -import { - Emitter, - Event, - addDisposableListener, -} from '../events'; +import { Emitter, Event, addDisposableListener } from '../events'; import { CompositeDisposable, MutableDisposable } from '../lifecycle'; import { clamp } from '../math'; import { AnchoredBox } from '../types'; @@ -34,9 +30,8 @@ class AriaLevelTracker { private update(): void { for (let i = 0; i < this._orderedList.length; i++) { this._orderedList[i].setAttribute('aria-level', `${i}`); - this._orderedList[ - i - ].style.zIndex = `calc(var(--dv-overlay-z-index, 999) + ${i * 2})`; + this._orderedList[i].style.zIndex = + `calc(var(--dv-overlay-z-index, 999) + ${i * 2})`; } } } @@ -438,7 +433,7 @@ export class Overlay extends CompositeDisposable { const iframes = disableIframePointEvents(); move.value = new CompositeDisposable( - addDisposableListener(window, 'pointermove', (e) => { + addDisposableListener(window, 'pointermove', (e) => { const containerRect = this.options.container.getBoundingClientRect(); const overlayRect = @@ -465,22 +460,22 @@ export class Overlay extends CompositeDisposable { let width: number | undefined = undefined; const moveTop = () => { - top = clamp( - y, - -Number.MAX_VALUE, + const maxTop = startPosition!.originalY + startPosition!.originalHeight > - containerRect.height - ? this.getMinimumHeight( - containerRect.height + containerRect.height + ? Math.max( + 0, + containerRect.height - + Overlay.MINIMUM_HEIGHT ) : Math.max( 0, startPosition!.originalY + startPosition!.originalHeight - Overlay.MINIMUM_HEIGHT - ) - ); + ); + top = clamp(y, 0, maxTop); height = startPosition!.originalY + @@ -495,35 +490,40 @@ export class Overlay extends CompositeDisposable { startPosition!.originalY - startPosition!.originalHeight; - height = clamp( - y - top, + const minHeight = top < 0 && - typeof this.options - .minimumInViewportHeight === 'number' + typeof this.options.minimumInViewportHeight === + 'number' ? -top + - this.options.minimumInViewportHeight - : Overlay.MINIMUM_HEIGHT, - Number.MAX_VALUE - ); + this.options.minimumInViewportHeight + : Overlay.MINIMUM_HEIGHT; + + const maxHeight = + containerRect.height - Math.max(0, top); + + height = clamp(y - top, minHeight, maxHeight); bottom = containerRect.height - top - height; }; const moveLeft = () => { - left = clamp( - x, - -Number.MAX_VALUE, + const maxLeft = startPosition!.originalX + startPosition!.originalWidth > - containerRect.width - ? this.getMinimumWidth(containerRect.width) + containerRect.width + ? Math.max( + 0, + containerRect.width - + Overlay.MINIMUM_WIDTH + ) : Math.max( 0, startPosition!.originalX + startPosition!.originalWidth - Overlay.MINIMUM_WIDTH - ) - ); + ); + + left = clamp(x, 0, maxLeft); width = startPosition!.originalX + @@ -538,16 +538,18 @@ export class Overlay extends CompositeDisposable { startPosition!.originalX - startPosition!.originalWidth; - width = clamp( - x - left, + const minWidth = left < 0 && - typeof this.options - .minimumInViewportWidth === 'number' + typeof this.options.minimumInViewportWidth === + 'number' ? -left + - this.options.minimumInViewportWidth - : Overlay.MINIMUM_WIDTH, - Number.MAX_VALUE - ); + this.options.minimumInViewportWidth + : Overlay.MINIMUM_WIDTH; + + const maxWidth = + containerRect.width - Math.max(0, left); + + width = clamp(x - left, minWidth, maxWidth); right = containerRect.width - left - width; }; From bd895d2b7f45bd5e337a1e010a69f3c3cec15e37 Mon Sep 17 00:00:00 2001 From: Pathan Aseef Khan Date: Fri, 31 Oct 2025 16:21:20 -0400 Subject: [PATCH 2/2] refactor: Add necessary comments --- packages/dockview-core/src/overlay/overlay.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/dockview-core/src/overlay/overlay.ts b/packages/dockview-core/src/overlay/overlay.ts index 26eb70aef..acc2e73b4 100644 --- a/packages/dockview-core/src/overlay/overlay.ts +++ b/packages/dockview-core/src/overlay/overlay.ts @@ -30,8 +30,9 @@ class AriaLevelTracker { private update(): void { for (let i = 0; i < this._orderedList.length; i++) { this._orderedList[i].setAttribute('aria-level', `${i}`); - this._orderedList[i].style.zIndex = - `calc(var(--dv-overlay-z-index, 999) + ${i * 2})`; + this._orderedList[ + i + ].style.zIndex = `calc(var(--dv-overlay-z-index, 999) + ${i * 2})`; } } } @@ -460,6 +461,7 @@ export class Overlay extends CompositeDisposable { let width: number | undefined = undefined; const moveTop = () => { + // When dragging top handle, constrain top position to prevent oversizing const maxTop = startPosition!.originalY + startPosition!.originalHeight > @@ -490,6 +492,7 @@ export class Overlay extends CompositeDisposable { startPosition!.originalY - startPosition!.originalHeight; + // When dragging bottom handle, constrain height to container height const minHeight = top < 0 && typeof this.options.minimumInViewportHeight === @@ -515,7 +518,7 @@ export class Overlay extends CompositeDisposable { 0, containerRect.width - Overlay.MINIMUM_WIDTH - ) + ) // Prevent extending beyong right edge : Math.max( 0, startPosition!.originalX + @@ -523,7 +526,7 @@ export class Overlay extends CompositeDisposable { Overlay.MINIMUM_WIDTH ); - left = clamp(x, 0, maxLeft); + left = clamp(x, 0, maxLeft); // min is 0 (Not -Infinity) to prevent dragging beyond left edge width = startPosition!.originalX + @@ -538,6 +541,7 @@ export class Overlay extends CompositeDisposable { startPosition!.originalX - startPosition!.originalWidth; + // When dragging right handle, constrain width to container width const minWidth = left < 0 && typeof this.options.minimumInViewportWidth ===