diff options
| author | 2023-12-15 10:08:56 +0800 | |
|---|---|---|
| committer | 2023-12-15 10:08:56 +0800 | |
| commit | d697a1774ad8571e9314e3bd85aa141170587d19 (patch) | |
| tree | cd3c3d84e3288db1f8e574a0b4dfb85e2e40f764 /src/templates/assets/javascripts/browser/element | |
| parent | 4943d5eff52a75caaccda6a1d84183032f06be26 (diff) | |
| parent | 4dafb0f0a81255193f2a44df5d203239325e2236 (diff) | |
| download | infini-d697a1774ad8571e9314e3bd85aa141170587d19.tar.gz infini-d697a1774ad8571e9314e3bd85aa141170587d19.zip | |
Merge branch 'master' into master
Diffstat (limited to 'src/templates/assets/javascripts/browser/element')
11 files changed, 0 insertions, 793 deletions
diff --git a/src/templates/assets/javascripts/browser/element/_/.eslintrc b/src/templates/assets/javascripts/browser/element/_/.eslintrc deleted file mode 100644 index 16973760..00000000 --- a/src/templates/assets/javascripts/browser/element/_/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "jsdoc/require-jsdoc": "off", - "jsdoc/require-returns-check": "off" - } -} diff --git a/src/templates/assets/javascripts/browser/element/_/index.ts b/src/templates/assets/javascripts/browser/element/_/index.ts deleted file mode 100644 index b7beb462..00000000 --- a/src/templates/assets/javascripts/browser/element/_/index.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve all elements matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Elements - */ -export function getElements<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T][] - -export function getElements<T extends HTMLElement>( - selector: string, node?: ParentNode -): T[] - -export function getElements<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T[] { - return Array.from(node.querySelectorAll<T>(selector)) -} - -/** - * Retrieve an element matching a query selector or throw a reference error - * - * Note that this function assumes that the element is present. If unsure if an - * element is existent, use the `getOptionalElement` function instead. - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element - */ -export function getElement<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] - -export function getElement<T extends HTMLElement>( - selector: string, node?: ParentNode -): T - -export function getElement<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T { - const el = getOptionalElement<T>(selector, node) - if (typeof el === "undefined") - throw new ReferenceError( - `Missing element: expected "${selector}" to be present` - ) - - /* Return element */ - return el -} - -/* ------------------------------------------------------------------------- */ - -/** - * Retrieve an optional element matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element or nothing - */ -export function getOptionalElement<T extends keyof HTMLElementTagNameMap>( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] | undefined - -export function getOptionalElement<T extends HTMLElement>( - selector: string, node?: ParentNode -): T | undefined - -export function getOptionalElement<T extends HTMLElement>( - selector: string, node: ParentNode = document -): T | undefined { - return node.querySelector<T>(selector) || undefined -} - -/** - * Retrieve the currently active element - * - * @returns Element or nothing - */ -export function getActiveElement(): HTMLElement | undefined { - return document.activeElement instanceof HTMLElement - ? document.activeElement || undefined - : undefined -} diff --git a/src/templates/assets/javascripts/browser/element/focus/index.ts b/src/templates/assets/javascripts/browser/element/focus/index.ts deleted file mode 100644 index f31fe276..00000000 --- a/src/templates/assets/javascripts/browser/element/focus/index.ts +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - debounceTime, - distinctUntilChanged, - fromEvent, - map, - merge, - shareReplay, - startWith -} from "rxjs" - -import { getActiveElement } from "../_" - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Focus observable - * - * Previously, this observer used `focus` and `blur` events to determine whether - * an element is focused, but this doesn't work if there are focusable elements - * within the elements itself. A better solutions are `focusin` and `focusout` - * events, which bubble up the tree and allow for more fine-grained control. - * - * `debounceTime` is necessary, because when a focus change happens inside an - * element, the observable would first emit `false` and then `true` again. - */ -const observer$ = merge( - fromEvent(document.body, "focusin"), - fromEvent(document.body, "focusout") -) - .pipe( - debounceTime(1), - startWith(undefined), - map(() => getActiveElement() || document.body), - shareReplay(1) - ) - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch element focus - * - * @param el - Element - * - * @returns Element focus observable - */ -export function watchElementFocus( - el: HTMLElement -): Observable<boolean> { - return observer$ - .pipe( - map(active => el.contains(active)), - distinctUntilChanged() - ) -} diff --git a/src/templates/assets/javascripts/browser/element/index.ts b/src/templates/assets/javascripts/browser/element/index.ts deleted file mode 100644 index 50ce84b2..00000000 --- a/src/templates/assets/javascripts/browser/element/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./focus" -export * from "./offset" -export * from "./size" -export * from "./visibility" diff --git a/src/templates/assets/javascripts/browser/element/offset/_/index.ts b/src/templates/assets/javascripts/browser/element/offset/_/index.ts deleted file mode 100644 index 6dd229d5..00000000 --- a/src/templates/assets/javascripts/browser/element/offset/_/index.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - animationFrameScheduler, - auditTime, - fromEvent, - map, - merge, - startWith -} from "rxjs" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementOffset { - x: number /* Horizontal offset */ - y: number /* Vertical offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element offset - * - * @param el - Element - * - * @returns Element offset - */ -export function getElementOffset( - el: HTMLElement -): ElementOffset { - return { - x: el.offsetLeft, - y: el.offsetTop - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element offset - * - * @param el - Element - * - * @returns Element offset observable - */ -export function watchElementOffset( - el: HTMLElement -): Observable<ElementOffset> { - return merge( - fromEvent(window, "load"), - fromEvent(window, "resize") - ) - .pipe( - auditTime(0, animationFrameScheduler), - map(() => getElementOffset(el)), - startWith(getElementOffset(el)) - ) -} diff --git a/src/templates/assets/javascripts/browser/element/offset/content/index.ts b/src/templates/assets/javascripts/browser/element/offset/content/index.ts deleted file mode 100644 index 557301a6..00000000 --- a/src/templates/assets/javascripts/browser/element/offset/content/index.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - animationFrameScheduler, - auditTime, - fromEvent, - map, - merge, - startWith -} from "rxjs" - -import { ElementOffset } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element content offset (= scroll offset) - * - * @param el - Element - * - * @returns Element content offset - */ -export function getElementContentOffset( - el: HTMLElement -): ElementOffset { - return { - x: el.scrollLeft, - y: el.scrollTop - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element content offset - * - * @param el - Element - * - * @returns Element content offset observable - */ -export function watchElementContentOffset( - el: HTMLElement -): Observable<ElementOffset> { - return merge( - fromEvent(el, "scroll"), - fromEvent(window, "resize") - ) - .pipe( - auditTime(0, animationFrameScheduler), - map(() => getElementContentOffset(el)), - startWith(getElementContentOffset(el)) - ) -} diff --git a/src/templates/assets/javascripts/browser/element/offset/index.ts b/src/templates/assets/javascripts/browser/element/offset/index.ts deleted file mode 100644 index 602ff2cf..00000000 --- a/src/templates/assets/javascripts/browser/element/offset/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./content" diff --git a/src/templates/assets/javascripts/browser/element/size/_/index.ts b/src/templates/assets/javascripts/browser/element/size/_/index.ts deleted file mode 100644 index 35a5e68b..00000000 --- a/src/templates/assets/javascripts/browser/element/size/_/index.ts +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - Subject, - defer, - filter, - finalize, - map, - merge, - of, - shareReplay, - startWith, - switchMap, - tap -} from "rxjs" - -import { watchScript } from "../../../script" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementSize { - width: number /* Element width */ - height: number /* Element height */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Resize observer entry subject - */ -const entry$ = new Subject<ResizeObserverEntry>() - -/** - * Resize observer observable - * - * This observable will create a `ResizeObserver` on the first subscription - * and will automatically terminate it when there are no more subscribers. - * It's quite important to centralize observation in a single `ResizeObserver`, - * as the performance difference can be quite dramatic, as the link shows. - * - * If the browser doesn't have a `ResizeObserver` implementation available, a - * polyfill is automatically downloaded from unpkg.com. This is also compatible - * with the built-in privacy plugin, which will download the polyfill and put - * it alongside the built site for self-hosting. - * - * @see https://bit.ly/3iIYfEm - Google Groups on performance - */ -const observer$ = defer(() => ( - typeof ResizeObserver === "undefined" - ? watchScript("https://unpkg.com/resize-observer-polyfill") - : of(undefined) -)) - .pipe( - map(() => new ResizeObserver(entries => { - for (const entry of entries) - entry$.next(entry) - })), - switchMap(observer => merge(NEVER, of(observer)) - .pipe( - finalize(() => observer.disconnect()) - ) - ), - shareReplay(1) - ) - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element size - * - * @param el - Element - * - * @returns Element size - */ -export function getElementSize( - el: HTMLElement -): ElementSize { - return { - width: el.offsetWidth, - height: el.offsetHeight - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element size - * - * This function returns an observable that subscribes to a single internal - * instance of `ResizeObserver` upon subscription, and emit resize events until - * termination. Note that this function should not be called with the same - * element twice, as the first unsubscription will terminate observation. - * - * Sadly, we can't use the `DOMRect` objects returned by the observer, because - * we need the emitted values to be consistent with `getElementSize`, which will - * return the used values (rounded) and not actual values (unrounded). Thus, we - * use the `offset*` properties. See the linked GitHub issue. - * - * @see https://bit.ly/3m0k3he - GitHub issue - * - * @param el - Element - * - * @returns Element size observable - */ -export function watchElementSize( - el: HTMLElement -): Observable<ElementSize> { - return observer$ - .pipe( - tap(observer => observer.observe(el)), - switchMap(observer => entry$ - .pipe( - filter(({ target }) => target === el), - finalize(() => observer.unobserve(el)), - map(() => getElementSize(el)) - ) - ), - startWith(getElementSize(el)) - ) -} diff --git a/src/templates/assets/javascripts/browser/element/size/content/index.ts b/src/templates/assets/javascripts/browser/element/size/content/index.ts deleted file mode 100644 index 5ed388cf..00000000 --- a/src/templates/assets/javascripts/browser/element/size/content/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { ElementSize } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element content size (= scroll width and height) - * - * @param el - Element - * - * @returns Element content size - */ -export function getElementContentSize( - el: HTMLElement -): ElementSize { - return { - width: el.scrollWidth, - height: el.scrollHeight - } -} - -/** - * Retrieve the overflowing container of an element, if any - * - * @param el - Element - * - * @returns Overflowing container or nothing - */ -export function getElementContainer( - el: HTMLElement -): HTMLElement | undefined { - let parent = el.parentElement - while (parent) - if ( - el.scrollWidth <= parent.scrollWidth && - el.scrollHeight <= parent.scrollHeight - ) - parent = (el = parent).parentElement - else - break - - /* Return overflowing container */ - return parent ? el : undefined -} diff --git a/src/templates/assets/javascripts/browser/element/size/index.ts b/src/templates/assets/javascripts/browser/element/size/index.ts deleted file mode 100644 index 602ff2cf..00000000 --- a/src/templates/assets/javascripts/browser/element/size/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./content" diff --git a/src/templates/assets/javascripts/browser/element/visibility/index.ts b/src/templates/assets/javascripts/browser/element/visibility/index.ts deleted file mode 100644 index 1ffe0b8d..00000000 --- a/src/templates/assets/javascripts/browser/element/visibility/index.ts +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2016-2023 Martin Donath <martin.donath@squidfunk.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - Subject, - defer, - distinctUntilChanged, - filter, - finalize, - map, - merge, - of, - shareReplay, - switchMap, - tap -} from "rxjs" - -import { - getElementContentSize, - getElementSize, - watchElementContentOffset -} from "~/browser" - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Intersection observer entry subject - */ -const entry$ = new Subject<IntersectionObserverEntry>() - -/** - * Intersection observer observable - * - * This observable will create an `IntersectionObserver` on first subscription - * and will automatically terminate it when there are no more subscribers. - * - * @see https://bit.ly/3iIYfEm - Google Groups on performance - */ -const observer$ = defer(() => of( - new IntersectionObserver(entries => { - for (const entry of entries) - entry$.next(entry) - }, { - threshold: 0 - }) -)) - .pipe( - switchMap(observer => merge(NEVER, of(observer)) - .pipe( - finalize(() => observer.disconnect()) - ) - ), - shareReplay(1) - ) - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch element visibility - * - * @param el - Element - * - * @returns Element visibility observable - */ -export function watchElementVisibility( - el: HTMLElement -): Observable<boolean> { - return observer$ - .pipe( - tap(observer => observer.observe(el)), - switchMap(observer => entry$ - .pipe( - filter(({ target }) => target === el), - finalize(() => observer.unobserve(el)), - map(({ isIntersecting }) => isIntersecting) - ) - ) - ) -} - -/** - * Watch element boundary - * - * This function returns an observable which emits whether the bottom content - * boundary (= scroll offset) of an element is within a certain threshold. - * - * @param el - Element - * @param threshold - Threshold - * - * @returns Element boundary observable - */ -export function watchElementBoundary( - el: HTMLElement, threshold = 16 -): Observable<boolean> { - return watchElementContentOffset(el) - .pipe( - map(({ y }) => { - const visible = getElementSize(el) - const content = getElementContentSize(el) - return y >= ( - content.height - visible.height - threshold - ) - }), - distinctUntilChanged() - ) -} |
