chore: format
This commit is contained in:
@@ -13,241 +13,263 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { fromEvent, merge, NEVER, combineLatest } from 'rxjs';
|
||||
import { fromEvent, merge, NEVER, combineLatest } from "rxjs";
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
filter,
|
||||
startWith,
|
||||
switchMap,
|
||||
tap,
|
||||
throttleTime,
|
||||
withLatestFrom,
|
||||
} from 'rxjs/operators';
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
filter,
|
||||
startWith,
|
||||
switchMap,
|
||||
tap,
|
||||
throttleTime,
|
||||
withLatestFrom,
|
||||
} from "rxjs/operators";
|
||||
|
||||
import {
|
||||
BREAK_POINT_3,
|
||||
BREAK_POINT_DYNAMIC,
|
||||
isSafari,
|
||||
isMobile,
|
||||
isMobileSafari,
|
||||
hasCSSOM,
|
||||
webComponentsReady,
|
||||
stylesheetReady,
|
||||
getScrollTop,
|
||||
getViewWidth,
|
||||
fromMediaQuery,
|
||||
} from './common';
|
||||
BREAK_POINT_3,
|
||||
BREAK_POINT_DYNAMIC,
|
||||
isSafari,
|
||||
isMobile,
|
||||
isMobileSafari,
|
||||
hasCSSOM,
|
||||
webComponentsReady,
|
||||
stylesheetReady,
|
||||
getScrollTop,
|
||||
getViewWidth,
|
||||
fromMediaQuery,
|
||||
} from "./common";
|
||||
|
||||
(async () => {
|
||||
await Promise.all([
|
||||
...('customElements' in window
|
||||
? []
|
||||
: [
|
||||
import(/* webpackChunkName: "webcomponents" */ './polyfills/webcomponents').then(() =>
|
||||
import(/* webpackChunkName: "shadydom" */ './polyfills/shadydom'),
|
||||
),
|
||||
]),
|
||||
...('ResizeObserver' in window
|
||||
? []
|
||||
: [import(/* webpackChunkName: "resize-observer" */ './polyfills/resize-observer')]),
|
||||
]);
|
||||
await Promise.all([
|
||||
...("customElements" in window
|
||||
? []
|
||||
: [
|
||||
import(
|
||||
/* webpackChunkName: "webcomponents" */ "./polyfills/webcomponents"
|
||||
).then(
|
||||
() =>
|
||||
import(/* webpackChunkName: "shadydom" */ "./polyfills/shadydom"),
|
||||
),
|
||||
]),
|
||||
...("ResizeObserver" in window
|
||||
? []
|
||||
: [
|
||||
import(
|
||||
/* webpackChunkName: "resize-observer" */ "./polyfills/resize-observer"
|
||||
),
|
||||
]),
|
||||
]);
|
||||
|
||||
await webComponentsReady;
|
||||
await stylesheetReady;
|
||||
await webComponentsReady;
|
||||
await stylesheetReady;
|
||||
|
||||
const MOBILE = 1;
|
||||
const DESKTOP = 2;
|
||||
const LARGE_DESKTOP = 3;
|
||||
const MOBILE = 1;
|
||||
const DESKTOP = 2;
|
||||
const LARGE_DESKTOP = 3;
|
||||
|
||||
const subscribeWhen = (p$) => (source) => {
|
||||
if (process.env.DEBUG && !p$) throw Error();
|
||||
return p$.pipe(switchMap((p) => (p ? source : NEVER)));
|
||||
};
|
||||
const subscribeWhen = (p$) => (source) => {
|
||||
if (process.env.DEBUG && !p$) throw Error();
|
||||
return p$.pipe(switchMap((p) => (p ? source : NEVER)));
|
||||
};
|
||||
|
||||
// Determines the range from which to draw the drawer in pixels, counted from the left edge.
|
||||
// It depends on the browser, e.g. Safari has a native gesture when sliding form the side,
|
||||
// so we ignore the first 35 pixels (roughly the range for the native gesture),
|
||||
// to avoid triggering both gestures.
|
||||
function getRange(drawerWidth, size) {
|
||||
if (size >= DESKTOP) return [0, drawerWidth];
|
||||
if (isMobileSafari) return [35, 150];
|
||||
return [0, 150];
|
||||
}
|
||||
// Determines the range from which to draw the drawer in pixels, counted from the left edge.
|
||||
// It depends on the browser, e.g. Safari has a native gesture when sliding form the side,
|
||||
// so we ignore the first 35 pixels (roughly the range for the native gesture),
|
||||
// to avoid triggering both gestures.
|
||||
function getRange(drawerWidth, size) {
|
||||
if (size >= DESKTOP) return [0, drawerWidth];
|
||||
if (isMobileSafari) return [35, 150];
|
||||
return [0, 150];
|
||||
}
|
||||
|
||||
// The functions below add an svg graphic to the sidebar
|
||||
// that indicate that the sidebar can be drawn using touch gestures.
|
||||
function setupIcon(drawerEl) {
|
||||
const img = document.getElementById('_hrefSwipeSVG');
|
||||
if (img) {
|
||||
const svg = document.createElement('img');
|
||||
svg.id = '_swipe';
|
||||
svg.src = img.href;
|
||||
svg.alt = 'Swipe image';
|
||||
svg.addEventListener('click', () => drawerEl.close());
|
||||
document.getElementById('_sidebar')?.appendChild(svg);
|
||||
}
|
||||
}
|
||||
// The functions below add an svg graphic to the sidebar
|
||||
// that indicate that the sidebar can be drawn using touch gestures.
|
||||
function setupIcon(drawerEl) {
|
||||
const img = document.getElementById("_hrefSwipeSVG");
|
||||
if (img) {
|
||||
const svg = document.createElement("img");
|
||||
svg.id = "_swipe";
|
||||
svg.src = img.href;
|
||||
svg.alt = "Swipe image";
|
||||
svg.addEventListener("click", () => drawerEl.close());
|
||||
document.getElementById("_sidebar")?.appendChild(svg);
|
||||
}
|
||||
}
|
||||
|
||||
function removeIcon() {
|
||||
const svg = document.getElementById('_swipe');
|
||||
svg?.parentNode?.removeChild(svg);
|
||||
}
|
||||
function removeIcon() {
|
||||
const svg = document.getElementById("_swipe");
|
||||
svg?.parentNode?.removeChild(svg);
|
||||
}
|
||||
|
||||
const detectSize = () =>
|
||||
window.matchMedia(BREAK_POINT_DYNAMIC).matches
|
||||
? LARGE_DESKTOP
|
||||
: window.matchMedia(BREAK_POINT_3).matches
|
||||
? DESKTOP
|
||||
: MOBILE;
|
||||
const detectSize = () =>
|
||||
window.matchMedia(BREAK_POINT_DYNAMIC).matches
|
||||
? LARGE_DESKTOP
|
||||
: window.matchMedia(BREAK_POINT_3).matches
|
||||
? DESKTOP
|
||||
: MOBILE;
|
||||
|
||||
// First we get hold of some DOM elements.
|
||||
const drawerEl = document.getElementById('_drawer');
|
||||
const sidebarEl = document.getElementById('_sidebar');
|
||||
const contentEl = sidebarEl?.querySelector('.sidebar-sticky');
|
||||
if (!drawerEl || !sidebarEl || !contentEl) return;
|
||||
// First we get hold of some DOM elements.
|
||||
const drawerEl = document.getElementById("_drawer");
|
||||
const sidebarEl = document.getElementById("_sidebar");
|
||||
const contentEl = sidebarEl?.querySelector(".sidebar-sticky");
|
||||
if (!drawerEl || !sidebarEl || !contentEl) return;
|
||||
|
||||
document.getElementById('_menu')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
drawerEl.toggle();
|
||||
});
|
||||
document.getElementById("_menu")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
drawerEl.toggle();
|
||||
});
|
||||
|
||||
sidebarEl
|
||||
.querySelectorAll('a[href^="/"]:not(.external)')
|
||||
.forEach((el) => el.addEventListener('click', () => drawerEl.close()));
|
||||
sidebarEl
|
||||
.querySelectorAll('a[href^="/"]:not(.external)')
|
||||
.forEach((el) => el.addEventListener("click", () => drawerEl.close()));
|
||||
|
||||
if (isSafari) drawerEl.setAttribute('threshold', '0');
|
||||
if (!isMobile) drawerEl.setAttribute('mouseevents', '');
|
||||
if (isSafari) drawerEl.setAttribute("threshold", "0");
|
||||
if (!isMobile) drawerEl.setAttribute("mouseevents", "");
|
||||
|
||||
const [tValue, oValue] = hasCSSOM
|
||||
? [new CSSTransformValue([new CSSTranslate(CSS.px(0), CSS.px(0))]), CSS.number(1)]
|
||||
: [null, null];
|
||||
const [tValue, oValue] = hasCSSOM
|
||||
? [
|
||||
new CSSTransformValue([new CSSTranslate(CSS.px(0), CSS.px(0))]),
|
||||
CSS.number(1),
|
||||
]
|
||||
: [null, null];
|
||||
|
||||
const updateSidebar = (t, size, distance) => {
|
||||
const value = distance * t;
|
||||
const opacity = size >= DESKTOP ? 1 : 1 - t;
|
||||
if (hasCSSOM) {
|
||||
tValue[0].x.value = value;
|
||||
oValue.value = opacity;
|
||||
sidebarEl.attributeStyleMap.set('transform', tValue);
|
||||
contentEl.attributeStyleMap.set('opacity', oValue);
|
||||
} else {
|
||||
sidebarEl.style.transform = `translateX(${value}px)`;
|
||||
contentEl.style.opacity = opacity;
|
||||
}
|
||||
};
|
||||
const updateSidebar = (t, size, distance) => {
|
||||
const value = distance * t;
|
||||
const opacity = size >= DESKTOP ? 1 : 1 - t;
|
||||
if (hasCSSOM) {
|
||||
tValue[0].x.value = value;
|
||||
oValue.value = opacity;
|
||||
sidebarEl.attributeStyleMap.set("transform", tValue);
|
||||
contentEl.attributeStyleMap.set("opacity", oValue);
|
||||
} else {
|
||||
sidebarEl.style.transform = `translateX(${value}px)`;
|
||||
contentEl.style.opacity = opacity;
|
||||
}
|
||||
};
|
||||
|
||||
// A flag for the 3 major viewport sizes we support
|
||||
const size$ = merge(
|
||||
fromMediaQuery(window.matchMedia(BREAK_POINT_3)),
|
||||
fromMediaQuery(window.matchMedia(BREAK_POINT_DYNAMIC)),
|
||||
).pipe(startWith({}), map(detectSize));
|
||||
// A flag for the 3 major viewport sizes we support
|
||||
const size$ = merge(
|
||||
fromMediaQuery(window.matchMedia(BREAK_POINT_3)),
|
||||
fromMediaQuery(window.matchMedia(BREAK_POINT_DYNAMIC)),
|
||||
).pipe(startWith({}), map(detectSize));
|
||||
|
||||
// An observable keeping track of the drawer (peek) width.
|
||||
const peekWidth$ = fromEvent(drawerEl, 'peek-width-change').pipe(map((e) => e.detail));
|
||||
// An observable keeping track of the drawer (peek) width.
|
||||
const peekWidth$ = fromEvent(drawerEl, "peek-width-change").pipe(
|
||||
map((e) => e.detail),
|
||||
);
|
||||
|
||||
// An observable keeping track the viewport width
|
||||
const viewWidth$ = fromEvent(window, 'resize', { passive: true }).pipe(startWith({}), map(getViewWidth));
|
||||
// An observable keeping track the viewport width
|
||||
const viewWidth$ = fromEvent(window, "resize", { passive: true }).pipe(
|
||||
startWith({}),
|
||||
map(getViewWidth),
|
||||
);
|
||||
|
||||
// An observable keeping track of the distance between
|
||||
// the middle point of the screen and the middle point of the drawer.
|
||||
const distance$ = combineLatest(peekWidth$, viewWidth$).pipe(
|
||||
map(([drawerWidth, viewWidth]) => viewWidth / 2 - drawerWidth / 2),
|
||||
);
|
||||
// An observable keeping track of the distance between
|
||||
// the middle point of the screen and the middle point of the drawer.
|
||||
const distance$ = combineLatest(peekWidth$, viewWidth$).pipe(
|
||||
map(([drawerWidth, viewWidth]) => viewWidth / 2 - drawerWidth / 2),
|
||||
);
|
||||
|
||||
const t$ = merge(
|
||||
distance$.pipe(map(() => (drawerEl.opacity !== undefined ? 1 - drawerEl.opacity : opened ? 0 : 1))),
|
||||
fromEvent(drawerEl, 'hy-drawer-move').pipe(
|
||||
map(({ detail: { opacity } }) => {
|
||||
return 1 - opacity;
|
||||
}),
|
||||
),
|
||||
);
|
||||
const t$ = merge(
|
||||
distance$.pipe(
|
||||
map(() =>
|
||||
drawerEl.opacity !== undefined ? 1 - drawerEl.opacity : opened ? 0 : 1,
|
||||
),
|
||||
),
|
||||
fromEvent(drawerEl, "hy-drawer-move").pipe(
|
||||
map(({ detail: { opacity } }) => {
|
||||
return 1 - opacity;
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
drawerEl.addEventListener('hy-drawer-prepare', () => {
|
||||
sidebarEl.style.willChange = 'transform';
|
||||
contentEl.style.willChange = 'opacity';
|
||||
});
|
||||
drawerEl.addEventListener("hy-drawer-prepare", () => {
|
||||
sidebarEl.style.willChange = "transform";
|
||||
contentEl.style.willChange = "opacity";
|
||||
});
|
||||
|
||||
drawerEl.addEventListener('hy-drawer-transitioned', () => {
|
||||
sidebarEl.style.willChange = '';
|
||||
contentEl.style.willChange = '';
|
||||
});
|
||||
drawerEl.addEventListener("hy-drawer-transitioned", () => {
|
||||
sidebarEl.style.willChange = "";
|
||||
contentEl.style.willChange = "";
|
||||
});
|
||||
|
||||
// Save scroll position before the drawer gets initialized.
|
||||
const scrollTop = getScrollTop();
|
||||
// Save scroll position before the drawer gets initialized.
|
||||
const scrollTop = getScrollTop();
|
||||
|
||||
// Start the drawer in `opened` state when the cover class is present,
|
||||
// and the user hasn't started scrolling already.
|
||||
const opened = drawerEl.classList.contains('cover') && scrollTop <= 0 && !(history.state && history.state.closedOnce);
|
||||
// Start the drawer in `opened` state when the cover class is present,
|
||||
// and the user hasn't started scrolling already.
|
||||
const opened =
|
||||
drawerEl.classList.contains("cover") &&
|
||||
scrollTop <= 0 &&
|
||||
!(history.state && history.state.closedOnce);
|
||||
|
||||
if (!opened) {
|
||||
if (!history.state) history.replaceState({}, document.title);
|
||||
history.state.closedOnce = true;
|
||||
drawerEl.removeAttribute('opened');
|
||||
}
|
||||
if (!opened) {
|
||||
if (!history.state) history.replaceState({}, document.title);
|
||||
history.state.closedOnce = true;
|
||||
drawerEl.removeAttribute("opened");
|
||||
}
|
||||
|
||||
const opened$ = fromEvent(drawerEl, 'hy-drawer-transitioned').pipe(
|
||||
map((e) => e.detail),
|
||||
distinctUntilChanged(),
|
||||
tap((opened) => {
|
||||
if (!opened) {
|
||||
removeIcon();
|
||||
if (!history.state) history.replaceState({}, document.title);
|
||||
history.state.closedOnce = true;
|
||||
}
|
||||
}),
|
||||
startWith(opened),
|
||||
);
|
||||
const opened$ = fromEvent(drawerEl, "hy-drawer-transitioned").pipe(
|
||||
map((e) => e.detail),
|
||||
distinctUntilChanged(),
|
||||
tap((opened) => {
|
||||
if (!opened) {
|
||||
removeIcon();
|
||||
if (!history.state) history.replaceState({}, document.title);
|
||||
history.state.closedOnce = true;
|
||||
}
|
||||
}),
|
||||
startWith(opened),
|
||||
);
|
||||
|
||||
// We need the height of the drawer in case we need to reset the scroll position
|
||||
const drawerHeight = opened ? null : drawerEl.getBoundingClientRect().height;
|
||||
// We need the height of the drawer in case we need to reset the scroll position
|
||||
const drawerHeight = opened ? null : drawerEl.getBoundingClientRect().height;
|
||||
|
||||
drawerEl.addEventListener(
|
||||
'hy-drawer-init',
|
||||
() => {
|
||||
drawerEl.classList.add('loaded');
|
||||
drawerEl.addEventListener(
|
||||
"hy-drawer-init",
|
||||
() => {
|
||||
drawerEl.classList.add("loaded");
|
||||
|
||||
setupIcon(drawerEl);
|
||||
setupIcon(drawerEl);
|
||||
|
||||
if (drawerHeight && scrollTop >= drawerHeight) {
|
||||
window.scrollTo(0, scrollTop - drawerHeight);
|
||||
}
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
if (drawerHeight && scrollTop >= drawerHeight) {
|
||||
window.scrollTo(0, scrollTop - drawerHeight);
|
||||
}
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
|
||||
await import(/* webpackMode: "eager" */ '@hydecorp/drawer');
|
||||
await import(/* webpackMode: "eager" */ "@hydecorp/drawer");
|
||||
|
||||
window._drawer = drawerEl;
|
||||
window._drawer = drawerEl;
|
||||
|
||||
t$.pipe(
|
||||
withLatestFrom(size$, distance$),
|
||||
tap((args) => updateSidebar(...args)),
|
||||
).subscribe();
|
||||
t$.pipe(
|
||||
withLatestFrom(size$, distance$),
|
||||
tap((args) => updateSidebar(...args)),
|
||||
).subscribe();
|
||||
|
||||
// Keeping the drawer updated.
|
||||
peekWidth$
|
||||
.pipe(
|
||||
withLatestFrom(size$),
|
||||
map((args) => getRange(...args)),
|
||||
tap((range) => {
|
||||
drawerEl.range = range;
|
||||
}),
|
||||
)
|
||||
.subscribe();
|
||||
// Keeping the drawer updated.
|
||||
peekWidth$
|
||||
.pipe(
|
||||
withLatestFrom(size$),
|
||||
map((args) => getRange(...args)),
|
||||
tap((range) => {
|
||||
drawerEl.range = range;
|
||||
}),
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
// Hacky way of letting the cover page close when scrolling
|
||||
fromEvent(document, 'wheel', { passive: false })
|
||||
.pipe(
|
||||
subscribeWhen(opened$),
|
||||
filter((e) => e.deltaY > 0),
|
||||
tap((e) => {
|
||||
if (drawerEl.translateX > 0) e.preventDefault();
|
||||
}),
|
||||
throttleTime(500),
|
||||
tap(() => drawerEl.close()),
|
||||
)
|
||||
.subscribe();
|
||||
// Hacky way of letting the cover page close when scrolling
|
||||
fromEvent(document, "wheel", { passive: false })
|
||||
.pipe(
|
||||
subscribeWhen(opened$),
|
||||
filter((e) => e.deltaY > 0),
|
||||
tap((e) => {
|
||||
if (drawerEl.translateX > 0) e.preventDefault();
|
||||
}),
|
||||
throttleTime(500),
|
||||
tap(() => drawerEl.close()),
|
||||
)
|
||||
.subscribe();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user