scrivito
Version:
Scrivito is a professional, yet easy to use SaaS Enterprise Content Management Service, built for digital agencies and medium to large businesses. It is completely maintenance-free, cost-effective, and has unprecedented performance and security.
88 lines (74 loc) • 2.36 kB
text/typescript
// @rewire
import { getCurrentPageId } from 'scrivito_sdk/app_support/get_current_page_id';
import { onReset, randomHex, scrollElementIntoView } from 'scrivito_sdk/common';
export type ScrollTarget = ObjFieldScrollTarget | WidgetScrollTarget;
type RevealCallback = () => void;
interface ObjFieldScrollTarget {
objId: string;
attributeName: string;
}
interface WidgetScrollTarget {
objId: string;
widgetId: string;
}
export function registerScrollTarget(
targetId: ScrollTarget,
element: Element,
onReveal?: RevealCallback
): () => void {
const targetKey = keyFor(targetId);
const id = randomHex();
const reveal = () => {
scrollElementIntoView(element, {
// See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView for details
// * Chrome and Firefox support all options
// * Safari supports the most important options: "block" and "inline" (tested with Safari 12.1.1)
// * Edge: Unknown
behavior: 'smooth',
block: 'center',
inline: 'center',
});
if (onReveal) onReveal();
};
const scrollTargets = scrollTargetRegistry[targetKey] || [];
scrollTargets.push({ id, reveal });
scrollTargetRegistry[targetKey] = scrollTargets;
if (requestedTargetId === targetKey) {
reveal();
requestedTargetId = '';
}
return () => {
const entries = scrollTargetRegistry[targetKey];
const remainingEntries = entries?.filter((entry) => entry.id !== id);
if (remainingEntries?.length) {
scrollTargetRegistry[targetKey] = remainingEntries;
} else {
delete scrollTargetRegistry[targetKey];
}
};
}
export function scrollIntoView(targetId: ScrollTarget): void {
if (targetId.objId !== getCurrentPageId()) return;
const targetKey = keyFor(targetId);
const entries = scrollTargetRegistry[targetKey];
if (entries) {
entries.forEach((entry) => entry.reveal());
} else {
requestedTargetId = targetKey;
}
}
function keyFor(targetId: {
objId: string;
attributeName?: string;
widgetId?: string;
}): string {
return [targetId.objId, targetId.attributeName, targetId.widgetId].toString();
}
let scrollTargetRegistry: {
[key: string]: Array<{ id: string; reveal: RevealCallback }> | undefined;
} = {};
let requestedTargetId: string;
onReset(() => {
scrollTargetRegistry = {};
requestedTargetId = '';
});