initial vitepress site with basic nav

This commit is contained in:
mrflos 2023-05-20 19:37:42 +03:00
parent a7df2e049d
commit 2029f16583
1900 changed files with 1014692 additions and 0 deletions

21
node_modules/body-scroll-lock/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Will Po
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 NONINFRINGEMENT. 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.

336
node_modules/body-scroll-lock/README.md generated vendored Normal file
View file

@ -0,0 +1,336 @@
<p align="left"> <img width="675" src="https://raw.githubusercontent.com/willmcpo/body-scroll-lock/master/images/logo.png" alt="Body scroll lock...just works with everything ;-)" /> </p>
## Why BSL?
Enables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus).
_Features:_
- disables body scroll WITHOUT disabling scroll of a target element
- works on iOS mobile/tablet (!!)
- works on Android
- works on Safari desktop
- works on Chrome/Firefox
- works with vanilla JS and frameworks such as React / Angular / VueJS
- supports nested target elements (eg. a modal that appears on top of a flyout)
- can reserve scrollbar width
- `-webkit-overflow-scrolling: touch` still works
_Aren't the alternative approaches sufficient?_
- the approach `document.body.ontouchmove = (e) => { e.preventDefault(); return false; };` locks the
body scroll, but ALSO locks the scroll of a target element (eg. modal).
- the approach `overflow: hidden` on the body or html elements doesn't work for all browsers
- the `position: fixed` approach causes the body scroll to reset
- some approaches break inertia/momentum/rubber-band scrolling on iOS
_LIGHT Package Size:_
[![minzip size](https://badgen.net/bundlephobia/minzip/body-scroll-lock?color=orange)](https://badgen.net/bundlephobia/minzip/body-scroll-lock?color=orange)
## Install
$ yarn add body-scroll-lock
or
$ npm install body-scroll-lock
You can also load via a `<script src="lib/bodyScrollLock.js"></script>` tag (refer to the lib folder).
## Usage examples
##### Common JS
```javascript
// 1. Import the functions
const bodyScrollLock = require('body-scroll-lock');
const disableBodyScroll = bodyScrollLock.disableBodyScroll;
const enableBodyScroll = bodyScrollLock.enableBodyScroll;
// 2. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav).
// Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element).
// This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired.
const targetElement = document.querySelector('#someElementId');
// 3. ...in some event handler after showing the target element...disable body scroll
disableBodyScroll(targetElement);
// 4. ...in some event handler after hiding the target element...
enableBodyScroll(targetElement);
```
##### React/ES6
```javascript
// 1. Import the functions
import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';
class SomeComponent extends React.Component {
targetElement = null;
componentDidMount() {
// 2. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav).
// Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element).
// This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired.
this.targetElement = document.querySelector('#targetElementId');
}
showTargetElement = () => {
// ... some logic to show target element
// 3. Disable body scroll
disableBodyScroll(this.targetElement);
};
hideTargetElement = () => {
// ... some logic to hide target element
// 4. Re-enable body scroll
enableBodyScroll(this.targetElement);
};
componentWillUnmount() {
// 5. Useful if we have called disableBodyScroll for multiple target elements,
// and we just want a kill-switch to undo all that.
// OR useful for if the `hideTargetElement()` function got circumvented eg. visitor
// clicks a link which takes him/her to a different page within the app.
clearAllBodyScrollLocks();
}
render() {
return <div>some JSX to go here</div>;
}
}
```
##### React/ES6 with Refs
```javascript
// 1. Import the functions
import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock';
class SomeComponent extends React.Component {
// 2. Initialise your ref and targetElement here
targetRef = React.createRef();
targetElement = null;
componentDidMount() {
// 3. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav).
// Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element).
// This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired.
this.targetElement = this.targetRef.current;
}
showTargetElement = () => {
// ... some logic to show target element
// 4. Disable body scroll
disableBodyScroll(this.targetElement);
};
hideTargetElement = () => {
// ... some logic to hide target element
// 5. Re-enable body scroll
enableBodyScroll(this.targetElement);
};
componentWillUnmount() {
// 5. Useful if we have called disableBodyScroll for multiple target elements,
// and we just want a kill-switch to undo all that.
// OR useful for if the `hideTargetElement()` function got circumvented eg. visitor
// clicks a link which takes him/her to a different page within the app.
clearAllBodyScrollLocks();
}
render() {
return (
// 6. Pass your ref with the reference to the targetElement to SomeOtherComponent
<SomeOtherComponent ref={this.targetRef}>some JSX to go here</SomeOtherComponent>
);
}
}
// 7. SomeOtherComponent needs to be a Class component to receive the ref (unless Hooks - https://reactjs.org/docs/hooks-faq.html#can-i-make-a-ref-to-a-function-component - are used).
class SomeOtherComponent extends React.Component {
componentDidMount() {
// Your logic on mount goes here
}
// 8. BSL will be applied to div below in SomeOtherComponent and persist scrolling for the container
render() {
return <div>some JSX to go here</div>;
}
}
```
##### Angular
```javascript
import { Component, ElementRef, OnDestroy, ViewChild } from "@angular/core";
// 1. Import the functions
import {
disableBodyScroll,
enableBodyScroll,
clearAllBodyScrollLocks
} from "body-scroll-lock";
@Component({
selector: "app-scroll-block",
templateUrl: "./scroll-block.component.html",
styleUrls: ["./scroll-block.component.css"]
})
export class SomeComponent implements OnDestroy {
// 2. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav).
// Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element).
// This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired.
@ViewChild("scrollTarget") scrollTarget: ElementRef;
showTargetElement() {
// ... some logic to show target element
// 3. Disable body scroll
disableBodyScroll(this.scrollTarget.nativeElement);
}
hideTargetElement() {
// ... some logic to hide target element
// 4. Re-enable body scroll
enableBodyScroll(this.scrollTarget.nativeElement);
}
ngOnDestroy() {
// 5. Useful if we have called disableBodyScroll for multiple target elements,
// and we just want a kill-switch to undo all that.
// OR useful for if the `hideTargetElement()` function got circumvented eg. visitor
// clicks a link which takes him/her to a different page within the app.
clearAllBodyScrollLocks();
}
}
```
##### Vanilla JS
In the html:
```html
<head>
<script src="some-path-where-you-dump-the-javascript-libraries/lib/bodyScrollLock.js"></script>
</head>
```
Then in the javascript:
```javascript
// 1. Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav).
// Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element).
// This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired.
const targetElement = document.querySelector('#someElementId');
// 2. ...in some event handler after showing the target element...disable body scroll
bodyScrollLock.disableBodyScroll(targetElement);
// 3. ...in some event handler after hiding the target element...
bodyScrollLock.enableBodyScroll(targetElement);
// 4. Useful if we have called disableBodyScroll for multiple target elements,
// and we just want a kill-switch to undo all that.
bodyScrollLock.clearAllBodyScrollLocks();
```
## Demo
Check out the demo, powered by Vercel.
* https://bodyscrolllock.vercel.app for a basic example
* https://bodyscrolllock-modal.vercel.app for an example with a modal.
## Functions
| Function | Arguments | Return | Description |
| :------------------------ | :------------------------------------------------------------- | :----: | :----------------------------------------------------------- |
| `disableBodyScroll` | `targetElement: HTMLElement` <br/>`options: BodyScrollOptions` | `void` | Disables body scroll while enabling scroll on target element |
| `enableBodyScroll` | `targetElement: HTMLElement` | `void` | Enables body scroll and removing listeners on target element |
| `clearAllBodyScrollLocks` | `null` | `void` | Clears all scroll locks |
## Options
### reserveScrollBarGap
**optional, default:** false
If the overflow property of the body is set to hidden, the body widens by the width of the scrollbar. This produces an
unpleasant flickering effect, especially on websites with centered content. If the `reserveScrollBarGap` option is set,
this gap is filled by a `padding-right` on the body element. If `disableBodyScroll` is called for the last target element,
or `clearAllBodyScrollLocks` is called, the `padding-right` is automatically reset to the previous value.
```js
import { disableBodyScroll } from 'body-scroll-lock';
import type { BodyScrollOptions } from 'body-scroll-lock';
const options: BodyScrollOptions = {
reserveScrollBarGap: true,
};
disableBodyScroll(targetElement, options);
```
### allowTouchMove
**optional, default:** undefined
To disable scrolling on iOS, `disableBodyScroll` prevents `touchmove` events.
However, there are cases where you have called `disableBodyScroll` on an
element, but its children still require `touchmove` events to function.
See below for 2 use cases:
##### Simple
```javascript
disableBodyScroll(container, {
allowTouchMove: el => el.tagName === 'TEXTAREA',
});
```
##### More Complex
Javascript:
```javascript
disableBodyScroll(container, {
allowTouchMove: el => {
while (el && el !== document.body) {
if (el.getAttribute('body-scroll-lock-ignore') !== null) {
return true;
}
el = el.parentElement;
}
},
});
```
Html:
```html
<div id="container">
<div id="scrolling-map" body-scroll-lock-ignore>
...
</div>
</div>
```
## References
https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177
https://stackoverflow.com/questions/41594997/ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-posi
## Changelog
Refer to the [releases](https://github.com/willmcpo/body-scroll-lock/releases) page.

262
node_modules/body-scroll-lock/lib/bodyScrollLock.es6.js generated vendored Normal file
View file

@ -0,0 +1,262 @@
// Older browsers don't support event options, feature detect it.
// Adopted and modified solution from Bohdan Didukh (2017)
// https://stackoverflow.com/questions/41594997/ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-posi
let hasPassiveEvents = false;
if (typeof window !== 'undefined') {
const passiveTestOptions = {
get passive() {
hasPassiveEvents = true;
return undefined;
}
};
window.addEventListener('testPassive', null, passiveTestOptions);
window.removeEventListener('testPassive', null, passiveTestOptions);
}
const 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);
let locks = [];
let documentListenerAdded = false;
let initialClientY = -1;
let previousBodyOverflowSetting;
let previousBodyPosition;
let previousBodyPaddingRight;
// returns true if `el` should be allowed to receive touchmove events.
const allowTouchMove = el => locks.some(lock => {
if (lock.options.allowTouchMove && lock.options.allowTouchMove(el)) {
return true;
}
return false;
});
const preventDefault = rawEvent => {
const e = rawEvent || window.event;
// For the case whereby consumers adds a touchmove event listener to document.
// Recall that we do document.addEventListener('touchmove', preventDefault, { passive: false })
// in disableBodyScroll - so if we provide this opportunity to allowTouchMove, then
// the touchmove event on document will break.
if (allowTouchMove(e.target)) {
return true;
}
// Do not prevent if the event has more than one touch (usually meaning this is a multi touch gesture like pinch to zoom).
if (e.touches.length > 1) return true;
if (e.preventDefault) e.preventDefault();
return false;
};
const setOverflowHidden = options => {
// If previousBodyPaddingRight is already set, don't set it again.
if (previousBodyPaddingRight === undefined) {
const reserveScrollBarGap = !!options && options.reserveScrollBarGap === true;
const scrollBarGap = window.innerWidth - document.documentElement.clientWidth;
if (reserveScrollBarGap && scrollBarGap > 0) {
const computedBodyPaddingRight = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'), 10);
previousBodyPaddingRight = document.body.style.paddingRight;
document.body.style.paddingRight = `${computedBodyPaddingRight + scrollBarGap}px`;
}
}
// If previousBodyOverflowSetting is already set, don't set it again.
if (previousBodyOverflowSetting === undefined) {
previousBodyOverflowSetting = document.body.style.overflow;
document.body.style.overflow = 'hidden';
}
};
const restoreOverflowSetting = () => {
if (previousBodyPaddingRight !== undefined) {
document.body.style.paddingRight = previousBodyPaddingRight;
// Restore previousBodyPaddingRight to undefined so setOverflowHidden knows it
// can be set again.
previousBodyPaddingRight = undefined;
}
if (previousBodyOverflowSetting !== undefined) {
document.body.style.overflow = previousBodyOverflowSetting;
// Restore previousBodyOverflowSetting to undefined
// so setOverflowHidden knows it can be set again.
previousBodyOverflowSetting = undefined;
}
};
const setPositionFixed = () => window.requestAnimationFrame(() => {
// If previousBodyPosition is already set, don't set it again.
if (previousBodyPosition === undefined) {
previousBodyPosition = {
position: document.body.style.position,
top: document.body.style.top,
left: document.body.style.left
};
// Update the dom inside an animation frame
const { scrollY, scrollX, innerHeight } = window;
document.body.style.position = 'fixed';
document.body.style.top = -scrollY;
document.body.style.left = -scrollX;
setTimeout(() => window.requestAnimationFrame(() => {
// 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);
}
}), 300);
}
});
const restorePositionSetting = () => {
if (previousBodyPosition !== undefined) {
// Convert the position from "px" to Int
const y = -parseInt(document.body.style.top, 10);
const x = -parseInt(document.body.style.left, 10);
// Restore styles
document.body.style.position = previousBodyPosition.position;
document.body.style.top = previousBodyPosition.top;
document.body.style.left = previousBodyPosition.left;
// Restore scroll
window.scrollTo(x, y);
previousBodyPosition = undefined;
}
};
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
const isTargetElementTotallyScrolled = targetElement => targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false;
const handleScroll = (event, targetElement) => {
const clientY = event.targetTouches[0].clientY - initialClientY;
if (allowTouchMove(event.target)) {
return false;
}
if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
// element is at the top of its scroll.
return preventDefault(event);
}
if (isTargetElementTotallyScrolled(targetElement) && clientY < 0) {
// element is at the bottom of its scroll.
return preventDefault(event);
}
event.stopPropagation();
return true;
};
export const disableBodyScroll = (targetElement, options) => {
// targetElement must be provided
if (!targetElement) {
// eslint-disable-next-line no-console
console.error('disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.');
return;
}
// disableBodyScroll must not have been called on this targetElement before
if (locks.some(lock => lock.targetElement === targetElement)) {
return;
}
const lock = {
targetElement,
options: options || {}
};
locks = [...locks, lock];
if (isIosDevice) {
setPositionFixed();
} else {
setOverflowHidden(options);
}
if (isIosDevice) {
targetElement.ontouchstart = event => {
if (event.targetTouches.length === 1) {
// detect single touch.
initialClientY = event.targetTouches[0].clientY;
}
};
targetElement.ontouchmove = event => {
if (event.targetTouches.length === 1) {
// detect single touch.
handleScroll(event, targetElement);
}
};
if (!documentListenerAdded) {
document.addEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = true;
}
}
};
export const clearAllBodyScrollLocks = () => {
if (isIosDevice) {
// Clear all locks ontouchstart/ontouchmove handlers, and the references.
locks.forEach(lock => {
lock.targetElement.ontouchstart = null;
lock.targetElement.ontouchmove = null;
});
if (documentListenerAdded) {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
// Reset initial clientY.
initialClientY = -1;
}
if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
locks = [];
};
export const enableBodyScroll = targetElement => {
if (!targetElement) {
// eslint-disable-next-line no-console
console.error('enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.');
return;
}
locks = locks.filter(lock => lock.targetElement !== targetElement);
if (isIosDevice) {
targetElement.ontouchstart = null;
targetElement.ontouchmove = null;
if (documentListenerAdded && locks.length === 0) {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
}
if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
};

278
node_modules/body-scroll-lock/lib/bodyScrollLock.esm.js generated vendored Normal file
View file

@ -0,0 +1,278 @@
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
// Older browsers don't support event options, feature detect it.
// Adopted and modified solution from Bohdan Didukh (2017)
// https://stackoverflow.com/questions/41594997/ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-posi
var hasPassiveEvents = false;
if (typeof window !== 'undefined') {
var passiveTestOptions = {
get passive() {
hasPassiveEvents = true;
return undefined;
}
};
window.addEventListener('testPassive', null, passiveTestOptions);
window.removeEventListener('testPassive', null, passiveTestOptions);
}
var 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);
var locks = [];
var documentListenerAdded = false;
var initialClientY = -1;
var previousBodyOverflowSetting = void 0;
var previousBodyPosition = void 0;
var previousBodyPaddingRight = void 0;
// returns true if `el` should be allowed to receive touchmove events.
var allowTouchMove = function allowTouchMove(el) {
return locks.some(function (lock) {
if (lock.options.allowTouchMove && lock.options.allowTouchMove(el)) {
return true;
}
return false;
});
};
var preventDefault = function preventDefault(rawEvent) {
var e = rawEvent || window.event;
// For the case whereby consumers adds a touchmove event listener to document.
// Recall that we do document.addEventListener('touchmove', preventDefault, { passive: false })
// in disableBodyScroll - so if we provide this opportunity to allowTouchMove, then
// the touchmove event on document will break.
if (allowTouchMove(e.target)) {
return true;
}
// Do not prevent if the event has more than one touch (usually meaning this is a multi touch gesture like pinch to zoom).
if (e.touches.length > 1) return true;
if (e.preventDefault) e.preventDefault();
return false;
};
var setOverflowHidden = function setOverflowHidden(options) {
// If previousBodyPaddingRight is already set, don't set it again.
if (previousBodyPaddingRight === undefined) {
var _reserveScrollBarGap = !!options && options.reserveScrollBarGap === true;
var scrollBarGap = window.innerWidth - document.documentElement.clientWidth;
if (_reserveScrollBarGap && scrollBarGap > 0) {
var computedBodyPaddingRight = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'), 10);
previousBodyPaddingRight = document.body.style.paddingRight;
document.body.style.paddingRight = computedBodyPaddingRight + scrollBarGap + 'px';
}
}
// If previousBodyOverflowSetting is already set, don't set it again.
if (previousBodyOverflowSetting === undefined) {
previousBodyOverflowSetting = document.body.style.overflow;
document.body.style.overflow = 'hidden';
}
};
var restoreOverflowSetting = function restoreOverflowSetting() {
if (previousBodyPaddingRight !== undefined) {
document.body.style.paddingRight = previousBodyPaddingRight;
// Restore previousBodyPaddingRight to undefined so setOverflowHidden knows it
// can be set again.
previousBodyPaddingRight = undefined;
}
if (previousBodyOverflowSetting !== undefined) {
document.body.style.overflow = previousBodyOverflowSetting;
// Restore previousBodyOverflowSetting to undefined
// so setOverflowHidden knows it can be set again.
previousBodyOverflowSetting = undefined;
}
};
var setPositionFixed = function setPositionFixed() {
return window.requestAnimationFrame(function () {
// If previousBodyPosition is already set, don't set it again.
if (previousBodyPosition === undefined) {
previousBodyPosition = {
position: document.body.style.position,
top: document.body.style.top,
left: document.body.style.left
};
// Update the dom inside an animation frame
var _window = window,
scrollY = _window.scrollY,
scrollX = _window.scrollX,
innerHeight = _window.innerHeight;
document.body.style.position = 'fixed';
document.body.style.top = -scrollY;
document.body.style.left = -scrollX;
setTimeout(function () {
return window.requestAnimationFrame(function () {
// Attempt to check if the bottom bar appeared due to the position change
var 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);
}
});
}, 300);
}
});
};
var restorePositionSetting = function restorePositionSetting() {
if (previousBodyPosition !== undefined) {
// Convert the position from "px" to Int
var y = -parseInt(document.body.style.top, 10);
var x = -parseInt(document.body.style.left, 10);
// Restore styles
document.body.style.position = previousBodyPosition.position;
document.body.style.top = previousBodyPosition.top;
document.body.style.left = previousBodyPosition.left;
// Restore scroll
window.scrollTo(x, y);
previousBodyPosition = undefined;
}
};
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
var isTargetElementTotallyScrolled = function isTargetElementTotallyScrolled(targetElement) {
return targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false;
};
var handleScroll = function handleScroll(event, targetElement) {
var clientY = event.targetTouches[0].clientY - initialClientY;
if (allowTouchMove(event.target)) {
return false;
}
if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
// element is at the top of its scroll.
return preventDefault(event);
}
if (isTargetElementTotallyScrolled(targetElement) && clientY < 0) {
// element is at the bottom of its scroll.
return preventDefault(event);
}
event.stopPropagation();
return true;
};
export var disableBodyScroll = function disableBodyScroll(targetElement, options) {
// targetElement must be provided
if (!targetElement) {
// eslint-disable-next-line no-console
console.error('disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.');
return;
}
// disableBodyScroll must not have been called on this targetElement before
if (locks.some(function (lock) {
return lock.targetElement === targetElement;
})) {
return;
}
var lock = {
targetElement: targetElement,
options: options || {}
};
locks = [].concat(_toConsumableArray(locks), [lock]);
if (isIosDevice) {
setPositionFixed();
} else {
setOverflowHidden(options);
}
if (isIosDevice) {
targetElement.ontouchstart = function (event) {
if (event.targetTouches.length === 1) {
// detect single touch.
initialClientY = event.targetTouches[0].clientY;
}
};
targetElement.ontouchmove = function (event) {
if (event.targetTouches.length === 1) {
// detect single touch.
handleScroll(event, targetElement);
}
};
if (!documentListenerAdded) {
document.addEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = true;
}
}
};
export var clearAllBodyScrollLocks = function clearAllBodyScrollLocks() {
if (isIosDevice) {
// Clear all locks ontouchstart/ontouchmove handlers, and the references.
locks.forEach(function (lock) {
lock.targetElement.ontouchstart = null;
lock.targetElement.ontouchmove = null;
});
if (documentListenerAdded) {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
// Reset initial clientY.
initialClientY = -1;
}
if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
locks = [];
};
export var enableBodyScroll = function enableBodyScroll(targetElement) {
if (!targetElement) {
// eslint-disable-next-line no-console
console.error('enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.');
return;
}
locks = locks.filter(function (lock) {
return lock.targetElement !== targetElement;
});
if (isIosDevice) {
targetElement.ontouchstart = null;
targetElement.ontouchmove = null;
if (documentListenerAdded && locks.length === 0) {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
}
if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
};

308
node_modules/body-scroll-lock/lib/bodyScrollLock.js generated vendored Normal file
View file

@ -0,0 +1,308 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(['exports'], factory);
} else if (typeof exports !== "undefined") {
factory(exports);
} else {
var mod = {
exports: {}
};
factory(mod.exports);
global.bodyScrollLock = mod.exports;
}
})(this, function (exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
// Older browsers don't support event options, feature detect it.
// Adopted and modified solution from Bohdan Didukh (2017)
// https://stackoverflow.com/questions/41594997/ios-10-safari-prevent-scrolling-behind-a-fixed-overlay-and-maintain-scroll-posi
var hasPassiveEvents = false;
if (typeof window !== 'undefined') {
var passiveTestOptions = {
get passive() {
hasPassiveEvents = true;
return undefined;
}
};
window.addEventListener('testPassive', null, passiveTestOptions);
window.removeEventListener('testPassive', null, passiveTestOptions);
}
var 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);
var locks = [];
var documentListenerAdded = false;
var initialClientY = -1;
var previousBodyOverflowSetting = void 0;
var previousBodyPosition = void 0;
var previousBodyPaddingRight = void 0;
// returns true if `el` should be allowed to receive touchmove events.
var allowTouchMove = function allowTouchMove(el) {
return locks.some(function (lock) {
if (lock.options.allowTouchMove && lock.options.allowTouchMove(el)) {
return true;
}
return false;
});
};
var preventDefault = function preventDefault(rawEvent) {
var e = rawEvent || window.event;
// For the case whereby consumers adds a touchmove event listener to document.
// Recall that we do document.addEventListener('touchmove', preventDefault, { passive: false })
// in disableBodyScroll - so if we provide this opportunity to allowTouchMove, then
// the touchmove event on document will break.
if (allowTouchMove(e.target)) {
return true;
}
// Do not prevent if the event has more than one touch (usually meaning this is a multi touch gesture like pinch to zoom).
if (e.touches.length > 1) return true;
if (e.preventDefault) e.preventDefault();
return false;
};
var setOverflowHidden = function setOverflowHidden(options) {
// If previousBodyPaddingRight is already set, don't set it again.
if (previousBodyPaddingRight === undefined) {
var _reserveScrollBarGap = !!options && options.reserveScrollBarGap === true;
var scrollBarGap = window.innerWidth - document.documentElement.clientWidth;
if (_reserveScrollBarGap && scrollBarGap > 0) {
var computedBodyPaddingRight = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'), 10);
previousBodyPaddingRight = document.body.style.paddingRight;
document.body.style.paddingRight = computedBodyPaddingRight + scrollBarGap + 'px';
}
}
// If previousBodyOverflowSetting is already set, don't set it again.
if (previousBodyOverflowSetting === undefined) {
previousBodyOverflowSetting = document.body.style.overflow;
document.body.style.overflow = 'hidden';
}
};
var restoreOverflowSetting = function restoreOverflowSetting() {
if (previousBodyPaddingRight !== undefined) {
document.body.style.paddingRight = previousBodyPaddingRight;
// Restore previousBodyPaddingRight to undefined so setOverflowHidden knows it
// can be set again.
previousBodyPaddingRight = undefined;
}
if (previousBodyOverflowSetting !== undefined) {
document.body.style.overflow = previousBodyOverflowSetting;
// Restore previousBodyOverflowSetting to undefined
// so setOverflowHidden knows it can be set again.
previousBodyOverflowSetting = undefined;
}
};
var setPositionFixed = function setPositionFixed() {
return window.requestAnimationFrame(function () {
// If previousBodyPosition is already set, don't set it again.
if (previousBodyPosition === undefined) {
previousBodyPosition = {
position: document.body.style.position,
top: document.body.style.top,
left: document.body.style.left
};
// Update the dom inside an animation frame
var _window = window,
scrollY = _window.scrollY,
scrollX = _window.scrollX,
innerHeight = _window.innerHeight;
document.body.style.position = 'fixed';
document.body.style.top = -scrollY;
document.body.style.left = -scrollX;
setTimeout(function () {
return window.requestAnimationFrame(function () {
// Attempt to check if the bottom bar appeared due to the position change
var 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);
}
});
}, 300);
}
});
};
var restorePositionSetting = function restorePositionSetting() {
if (previousBodyPosition !== undefined) {
// Convert the position from "px" to Int
var y = -parseInt(document.body.style.top, 10);
var x = -parseInt(document.body.style.left, 10);
// Restore styles
document.body.style.position = previousBodyPosition.position;
document.body.style.top = previousBodyPosition.top;
document.body.style.left = previousBodyPosition.left;
// Restore scroll
window.scrollTo(x, y);
previousBodyPosition = undefined;
}
};
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
var isTargetElementTotallyScrolled = function isTargetElementTotallyScrolled(targetElement) {
return targetElement ? targetElement.scrollHeight - targetElement.scrollTop <= targetElement.clientHeight : false;
};
var handleScroll = function handleScroll(event, targetElement) {
var clientY = event.targetTouches[0].clientY - initialClientY;
if (allowTouchMove(event.target)) {
return false;
}
if (targetElement && targetElement.scrollTop === 0 && clientY > 0) {
// element is at the top of its scroll.
return preventDefault(event);
}
if (isTargetElementTotallyScrolled(targetElement) && clientY < 0) {
// element is at the bottom of its scroll.
return preventDefault(event);
}
event.stopPropagation();
return true;
};
var disableBodyScroll = exports.disableBodyScroll = function disableBodyScroll(targetElement, options) {
// targetElement must be provided
if (!targetElement) {
// eslint-disable-next-line no-console
console.error('disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.');
return;
}
// disableBodyScroll must not have been called on this targetElement before
if (locks.some(function (lock) {
return lock.targetElement === targetElement;
})) {
return;
}
var lock = {
targetElement: targetElement,
options: options || {}
};
locks = [].concat(_toConsumableArray(locks), [lock]);
if (isIosDevice) {
setPositionFixed();
} else {
setOverflowHidden(options);
}
if (isIosDevice) {
targetElement.ontouchstart = function (event) {
if (event.targetTouches.length === 1) {
// detect single touch.
initialClientY = event.targetTouches[0].clientY;
}
};
targetElement.ontouchmove = function (event) {
if (event.targetTouches.length === 1) {
// detect single touch.
handleScroll(event, targetElement);
}
};
if (!documentListenerAdded) {
document.addEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = true;
}
}
};
var clearAllBodyScrollLocks = exports.clearAllBodyScrollLocks = function clearAllBodyScrollLocks() {
if (isIosDevice) {
// Clear all locks ontouchstart/ontouchmove handlers, and the references.
locks.forEach(function (lock) {
lock.targetElement.ontouchstart = null;
lock.targetElement.ontouchmove = null;
});
if (documentListenerAdded) {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
// Reset initial clientY.
initialClientY = -1;
}
if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
locks = [];
};
var enableBodyScroll = exports.enableBodyScroll = function enableBodyScroll(targetElement) {
if (!targetElement) {
// eslint-disable-next-line no-console
console.error('enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.');
return;
}
locks = locks.filter(function (lock) {
return lock.targetElement !== targetElement;
});
if (isIosDevice) {
targetElement.ontouchstart = null;
targetElement.ontouchmove = null;
if (documentListenerAdded && locks.length === 0) {
document.removeEventListener('touchmove', preventDefault, hasPassiveEvents ? { passive: false } : undefined);
documentListenerAdded = false;
}
}
if (isIosDevice) {
restorePositionSetting();
} else {
restoreOverflowSetting();
}
};
});

View file

@ -0,0 +1 @@
!function(e,o){if("function"==typeof define&&define.amd)define(["exports"],o);else if("undefined"!=typeof exports)o(exports);else{var t={};o(t),e.bodyScrollLock=t}}(this,function(exports){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=!1;if("undefined"!=typeof window){var e={get passive(){t=!0}};window.addEventListener("testPassive",null,e),window.removeEventListener("testPassive",null,e)}var n="undefined"!=typeof window&&window.navigator&&window.navigator.platform&&(/iP(ad|hone|od)/.test(window.navigator.platform)||"MacIntel"===window.navigator.platform&&1<window.navigator.maxTouchPoints),i=[],d=!1,l=-1,c=void 0,s=void 0,u=void 0,a=function(o){return i.some(function(e){return!(!e.options.allowTouchMove||!e.options.allowTouchMove(o))})},v=function(e){var o=e||window.event;return!!a(o.target)||(1<o.touches.length||(o.preventDefault&&o.preventDefault(),!1))},r=function(){void 0!==u&&(document.body.style.paddingRight=u,u=void 0),void 0!==c&&(document.body.style.overflow=c,c=void 0)},f=function(){if(void 0!==s){var e=-parseInt(document.body.style.top,10),o=-parseInt(document.body.style.left,10);document.body.style.position=s.position,document.body.style.top=s.top,document.body.style.left=s.left,window.scrollTo(o,e),s=void 0}};exports.disableBodyScroll=function(r,e){if(r){if(!i.some(function(e){return e.targetElement===r})){var o={targetElement:r,options:e||{}};i=[].concat(function(e){if(Array.isArray(e)){for(var o=0,t=Array(e.length);o<e.length;o++)t[o]=e[o];return t}return Array.from(e)}(i),[o]),n?window.requestAnimationFrame(function(){if(void 0===s){s={position:document.body.style.position,top:document.body.style.top,left:document.body.style.left};var e=window,o=e.scrollY,t=e.scrollX,n=e.innerHeight;document.body.style.position="fixed",document.body.style.top=-o,document.body.style.left=-t,setTimeout(function(){return window.requestAnimationFrame(function(){var e=n-window.innerHeight;e&&n<=o&&(document.body.style.top=-(o+e))})},300)}}):function(e){if(void 0===u){var o=!!e&&!0===e.reserveScrollBarGap,t=window.innerWidth-document.documentElement.clientWidth;if(o&&0<t){var n=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right"),10);u=document.body.style.paddingRight,document.body.style.paddingRight=n+t+"px"}}void 0===c&&(c=document.body.style.overflow,document.body.style.overflow="hidden")}(e),n&&(r.ontouchstart=function(e){1===e.targetTouches.length&&(l=e.targetTouches[0].clientY)},r.ontouchmove=function(e){var o,t,n,i;1===e.targetTouches.length&&(t=r,i=(o=e).targetTouches[0].clientY-l,!a(o.target)&&(t&&0===t.scrollTop&&0<i?v(o):(n=t)&&n.scrollHeight-n.scrollTop<=n.clientHeight&&i<0?v(o):o.stopPropagation()))},d||(document.addEventListener("touchmove",v,t?{passive:!1}:void 0),d=!0))}}else console.error("disableBodyScroll unsuccessful - targetElement must be provided when calling disableBodyScroll on IOS devices.")},exports.clearAllBodyScrollLocks=function(){n&&(i.forEach(function(e){e.targetElement.ontouchstart=null,e.targetElement.ontouchmove=null}),d&&(document.removeEventListener("touchmove",v,t?{passive:!1}:void 0),d=!1),l=-1),n?f():r(),i=[]},exports.enableBodyScroll=function(o){o?(i=i.filter(function(e){return e.targetElement!==o}),n&&(o.ontouchstart=null,o.ontouchmove=null,d&&0===i.length&&(document.removeEventListener("touchmove",v,t?{passive:!1}:void 0),d=!1)),n?f():r()):console.error("enableBodyScroll unsuccessful - targetElement must be provided when calling enableBodyScroll on IOS devices.")}});

78
node_modules/body-scroll-lock/package.json generated vendored Normal file
View file

@ -0,0 +1,78 @@
{
"name": "body-scroll-lock",
"version": "4.0.0-beta.0",
"description": "Enables body scroll locking (for iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox) without breaking scrolling of a target element (eg. modal/lightbox/flyouts/nav-menus)",
"main": "lib/bodyScrollLock.min.js",
"module": "lib/bodyScrollLock.esm.js",
"author": "Will Po",
"repository": "https://github.com/willmcpo/body-scroll-lock.git",
"license": "MIT",
"files": [
"lib"
],
"keywords": [
"body scroll",
"body scroll lock",
"react scroll lock",
"react scroll",
"scroll",
"lock",
"freeze",
"toggle",
"disable",
"overflow",
"modal",
"lightbox",
"react",
"vanilla-js",
"angular",
"vue",
"ios",
"mobile",
"desktop",
"tablet",
"bsl"
],
"dependencies": {},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-eslint": "^10.1.0",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-preset-env": "^1.6.1",
"babel-preset-flow": "^6.23.0",
"babel-preset-stage-0": "^6.24.1",
"eslint": "^6.8.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-babel": "^9.0.0",
"eslint-config-prettier": "^6.0.0",
"eslint-plugin-flowtype": "^4.6.0",
"eslint-plugin-import": "^2.8.0",
"flow-bin": "^0.120.1",
"husky": "^4.2.3",
"jest": "^25.1.0",
"lint-staged": "^10.0.8",
"prettier": "^1.10.2",
"rimraf": "^3.0.2",
"uglify-js": "^3.4.7"
},
"scripts": {
"clean": "rimraf lib/ && mkdir -p ./lib",
"release": "npm version",
"postrelease": "yarn publish && git push --follow-tags",
"buildModule": "BABEL_ENV=module babel src/bodyScrollLock.js > lib/bodyScrollLock.esm.js",
"buildEs6": "BABEL_ENV=es6 babel src/bodyScrollLock.js > lib/bodyScrollLock.es6.js",
"buildUmd": "BABEL_ENV=umd babel src/bodyScrollLock.js > lib/bodyScrollLock.js && uglifyjs --compress unused,dead_code --mangle reserved=['require','exports'] lib/bodyScrollLock.js > lib/bodyScrollLock.min.js",
"build": "yarn buildModule && yarn buildEs6 && yarn buildUmd",
"lint": "eslint ./src",
"prerelease": "yarn flow && yarn lint && yarn run clean && yarn build",
"flow": "flow",
"prettierAll": "prettier --write '**/*.{md,json,js,html,yml}'",
"precommit": "lint-staged"
},
"lint-staged": {
"*.js": [
"prettier --write --single-quote --trailing-comma es5 --print-width 120",
"git add"
]
}
}