From 95c66b99e381b999d40ce0c1e0b2f9a0a8e51da6 Mon Sep 17 00:00:00 2001 From: squidfunk Date: Mon, 17 Feb 2020 11:35:36 +0100 Subject: [PATCH] Refactored search lock --- .../actions/main/scrollable/index.ts | 30 ++++++++ src/assets/javascripts/index.ts | 68 ++++++++----------- 2 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/assets/javascripts/actions/main/scrollable/index.ts b/src/assets/javascripts/actions/main/scrollable/index.ts index 187331883..7b0e0ff61 100644 --- a/src/assets/javascripts/actions/main/scrollable/index.ts +++ b/src/assets/javascripts/actions/main/scrollable/index.ts @@ -45,3 +45,33 @@ export function resetOverflowScrolling( ): void { el.style.webkitOverflowScrolling = "" } + +/* ------------------------------------------------------------------------- */ + +/** + * Set scroll lock + * + * @param el - Scrollable element + * @param value - Vertical offset + */ +export function setScrollLock( + el: HTMLElement, value: number +): void { + el.setAttribute("data-md-state", "lock") + el.style.top = `-${value}px` +} + +/** + * Reset scroll lock + * + * @param el - Scrollable element + */ +export function resetScrollLock( + el: HTMLElement +): void { + const value = -1 * parseInt(el.style.top, 10) + el.removeAttribute("data-md-state") + el.style.top = "" + if (value) + window.scrollTo(0, value) +} diff --git a/src/assets/javascripts/index.ts b/src/assets/javascripts/index.ts index 8f8eedfd9..159cd5f87 100644 --- a/src/assets/javascripts/index.ts +++ b/src/assets/javascripts/index.ts @@ -32,7 +32,8 @@ import { merge, of, NEVER, - combineLatest + combineLatest, + animationFrameScheduler } from "rxjs" import { delay, @@ -45,7 +46,8 @@ import { bufferCount, startWith, pluck, - withLatestFrom + withLatestFrom, + observeOn } from "rxjs/operators" import { @@ -67,7 +69,7 @@ import { import { setupSearchWorker } from "./workers" import { renderSource } from "templates" import { fetchGitHubStats } from "integrations/source/github" -import { setToggle } from "actions" +import { setToggle, setScrollLock, resetScrollLock } from "actions" import { Component, mountHeader, @@ -83,6 +85,7 @@ import { import { mountClipboard } from "./integrations/clipboard" import { patchTables, patchDetails } from "patches" import { takeIf, not, isConfig } from "utilities" +import { setSearchLock } from "actions/search/_" /* ------------------------------------------------------------------------- */ @@ -306,6 +309,29 @@ export function initialize(config: unknown) { ) .subscribe() + // scroll lock + const toggle$ = useToggle("search") + combineLatest([ + toggle$.pipe(switchMap(watchToggle)), + tablet$, + ]) + .pipe( + withLatestFrom(viewport$), + switchMap(([[toggle, tablet], { offset: { y }}]) => { + const active = toggle && !tablet + return of(document.body) + .pipe( + delay(active ? 400 : 100), + observeOn(animationFrameScheduler), + tap(el => active + ? setScrollLock(el, y) + : resetScrollLock(el) + ) + ) + }) + ) + .subscribe() + /* ----------------------------------------------------------------------- */ // watchClipboard @@ -332,42 +358,6 @@ export function initialize(config: unknown) { patchDetails({ document$ }) .subscribe() - // scroll lock - let scroll = 0 - combineLatest([ - useToggle("search") - .pipe( - switchMap(watchToggle) - ), - tablet$, - ]).pipe( - tap(([toggle, tablet]) => { - if (toggle && !tablet) { - scroll = scrollY - setTimeout(() => { - requestAnimationFrame(() => { - document.body.style.position = 'fixed'; - document.body.style.top = `-${scroll}px`; - // data.mdState = lock - }) - }, 400) - } else { - - /* Scroll to former position, but wait for 100ms to prevent flashes on - iOS. A short timeout seems to do the trick */ - setTimeout(() => { - requestAnimationFrame(() => { - document.body.style.position = ''; - document.body.style.top = ''; - if (scroll) - window.scrollTo(0, scroll) - }) - }, 100) - } - }) - ) - .subscribe() - /* Force 1px scroll offset to trigger overflow scrolling */ if (true || navigator.userAgent.match(/(iPad|iPhone|iPod)/g)) { const scrollable = document.querySelectorAll("[data-md-scrollfix]")