From 1350e2f6e3d7981db81093f8dac5c3afdb97c8e8 Mon Sep 17 00:00:00 2001 From: mimshins Date: Sun, 18 May 2025 20:16:33 +0330 Subject: [PATCH] Remove iOS-specific behaviors xD --- .changeset/sad-webs-fall.md | 6 + .../src/utils/controllers/ScrollLocker.ts | 190 +----------------- 2 files changed, 9 insertions(+), 187 deletions(-) create mode 100644 .changeset/sad-webs-fall.md diff --git a/.changeset/sad-webs-fall.md b/.changeset/sad-webs-fall.md new file mode 100644 index 00000000..9904cbf8 --- /dev/null +++ b/.changeset/sad-webs-fall.md @@ -0,0 +1,6 @@ +--- +"@tapsioss/web-components": patch +--- + +Remove iOS-specific behaviors xD + \ No newline at end of file diff --git a/packages/web-components/src/utils/controllers/ScrollLocker.ts b/packages/web-components/src/utils/controllers/ScrollLocker.ts index b436e896..c89799ce 100644 --- a/packages/web-components/src/utils/controllers/ScrollLocker.ts +++ b/packages/web-components/src/utils/controllers/ScrollLocker.ts @@ -1,6 +1,3 @@ -import { runBeforeRepaint } from "../event-loop-execution.ts"; -import isSsr from "../is-ssr.ts"; - type LockOptions = { reserveScrollBarGap?: boolean; allowTouchMove?: (element: HTMLElement) => boolean; @@ -14,15 +11,8 @@ type Lock = { type HandleScrollEvent = TouchEvent; class ScrollLocker { - private _hasPassiveEvents = false; - private _isIosDevice = false; - private _locks: Array = []; - private _documentListenerAdded: boolean = false; - - private _initialClientY: number = -1; - private _cachedBodySettings: { overflow: string; positioning: { @@ -40,36 +30,6 @@ class ScrollLocker { constructor() { this._preventDefault = this._preventDefault.bind(this); - - if (!isSsr()) { - let hasPassiveEvents = false; - - const passiveTestOptions = { - get passive() { - hasPassiveEvents = true; - return undefined; - }, - }; - - /* eslint-disable @typescript-eslint/ban-ts-comment */ - // @ts-ignore - window.addEventListener("test-passive", null, passiveTestOptions); - // @ts-ignore - window.removeEventListener("test-passive", null); - /* eslint-enable @typescript-eslint/ban-ts-comment */ - - this._isIosDevice = - typeof window !== "undefined" && - !!window.navigator && - ((!!window.navigator.platform && - (/iP(ad|hone|od)/.test(window.navigator.platform) || - (window.navigator.platform === "MacIntel" && - window.navigator.maxTouchPoints > 1))) || - (!!window.navigator.userAgent && - /iP(ad|hone|od)/.test(window.navigator.userAgent))); - - this._hasPassiveEvents = hasPassiveEvents; - } } /** @@ -135,92 +95,6 @@ class ScrollLocker { this._cachedBodySettings.overflow = ""; } - private _setPositionFixed() { - window.requestAnimationFrame(() => { - if (!this._cachedBodySettings.positioning) { - this._cachedBodySettings.positioning = { - position: document.body.style.position, - top: document.body.style.top, - left: document.body.style.left, - right: document.body.style.right, - }; - - // Update the dom inside an animation frame - const { scrollY, scrollX, innerHeight } = window; - - document.body.style.position = "fixed"; - document.body.style.top = `${-scrollY}px`; - document.body.style.left = `${-scrollX}px`; - document.body.style.right = `0`; - - runBeforeRepaint(() => { - // Attempt to check if the bottom bar appeared due to the position change - const bottomBarHeight = innerHeight - window.innerHeight; - - if (bottomBarHeight && scrollY >= innerHeight) { - // Move the content further up so that the bottom bar doesn't hide it - document.body.style.top = `${-(scrollY + bottomBarHeight)}px`; - } - }); - } - }); - } - - private _restorePositionSetting() { - // Convert the position from "px" to Int - const y = -parseInt(document.body.style.top, 10); - const x = -parseInt(document.body.style.left, 10); - - const { - left = "", - position = "", - top = "", - right = "", - } = this._cachedBodySettings.positioning ?? {}; - - // Restore styles - document.body.style.position = position; - document.body.style.top = top; - document.body.style.left = left; - document.body.style.right = right; - - // Restore scroll - window.scrollTo(x, y); - - this._cachedBodySettings.positioning = null; - } - - // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions - private _isTargetElementTotallyScrolled(targetElement: HTMLElement) { - if (!targetElement) return false; - - return ( - targetElement.scrollHeight - targetElement.scrollTop <= - targetElement.clientHeight - ); - } - - private _handleScroll(event: HandleScrollEvent, targetElement: HTMLElement) { - const touchY = event.targetTouches[0]?.clientY ?? 0; - const clientY = touchY - this._initialClientY; - - if (this._allowTouchMove(event.target as HTMLElement)) return false; - - if (targetElement && targetElement.scrollTop === 0 && clientY > 0) { - // Element is at the top of its scroll. - return this._preventDefault(event); - } - - if (this._isTargetElementTotallyScrolled(targetElement) && clientY < 0) { - // Element is at the bottom of its scroll. - return this._preventDefault(event); - } - - event.stopPropagation(); - - return true; - } - public lock(targetElement: HTMLElement, options?: LockOptions): void { const alreadyLocked = this._locks.some( lock => lock.targetElement === targetElement, @@ -234,57 +108,11 @@ class ScrollLocker { }; this._locks.push(lock); - - if (this._isIosDevice) this._setPositionFixed(); - else this._setOverflowHidden(options); - - if (this._isIosDevice) { - targetElement.ontouchstart = (event: HandleScrollEvent) => { - if (event.targetTouches.length === 1) { - // Detect single touch. - this._initialClientY = event.targetTouches[0]!.clientY; - } - }; - - targetElement.ontouchmove = (event: HandleScrollEvent) => { - if (event.targetTouches.length === 1) { - // Detect single touch. - this._handleScroll(event, targetElement); - } - }; - - if (!this._documentListenerAdded) { - document.addEventListener( - "touchmove", - this._preventDefault, - this._hasPassiveEvents ? { passive: false } : undefined, - ); - - this._documentListenerAdded = true; - } - } + this._setOverflowHidden(options); } public clearLocks(): void { - if (this._isIosDevice) { - // Clear all locks ontouchstart/ontouchmove handlers, and the references. - this._locks.forEach((lock: Lock) => { - lock.targetElement.ontouchstart = null; - lock.targetElement.ontouchmove = null; - }); - - if (this._documentListenerAdded) { - document.removeEventListener("touchmove", this._preventDefault); - - this._documentListenerAdded = false; - } - - // Reset initial clientY. - this._initialClientY = -1; - } - - if (this._isIosDevice) this._restorePositionSetting(); - else this._restoreOverflowSetting(); + this._restoreOverflowSetting(); this._locks = []; } @@ -294,19 +122,7 @@ class ScrollLocker { lock => lock.targetElement !== targetElement, ); - if (this._isIosDevice) { - targetElement.ontouchstart = null; - targetElement.ontouchmove = null; - - if (this._documentListenerAdded && this._locks.length === 0) { - document.removeEventListener("touchmove", this._preventDefault); - - this._documentListenerAdded = false; - } - } - - if (this._isIosDevice) this._restorePositionSetting(); - else this._restoreOverflowSetting(); + this._restoreOverflowSetting(); } }