Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 1x 1x | import {
WH,
CacheValues,
createDiv,
offsetSize,
runEach,
prependChildren,
removeElements,
createCache,
push,
IntersectionObserverConstructor,
} from 'support';
import { createSizeObserver } from 'observers/sizeObserver';
import { classNameTrinsicObserver } from 'classnames';
export interface TrinsicObserver {
_destroy(): void;
_getCurrentCacheValues(
force?: boolean
): {
_heightIntrinsic: CacheValues<boolean>;
};
}
const isHeightIntrinsic = (ioEntryOrSize: IntersectionObserverEntry | WH<number>): boolean =>
(ioEntryOrSize as WH<number>).h === 0 ||
(ioEntryOrSize as IntersectionObserverEntry).isIntersecting ||
(ioEntryOrSize as IntersectionObserverEntry).intersectionRatio > 0;
/**
* Creates a trinsic observer which observes changes to intrinsic or extrinsic sizing for the height of the target element.
* @param target The element which shall be observed.
* @param onTrinsicChangedCallback The callback which gets called after a change was detected.
* @returns A object which represents the instance of the trinsic observer.
*/
export const createTrinsicObserver = (
target: HTMLElement,
onTrinsicChangedCallback: (heightIntrinsic: CacheValues<boolean>) => any
): TrinsicObserver => {
const trinsicObserver = createDiv(classNameTrinsicObserver);
const offListeners: (() => void)[] = [];
const [updateHeightIntrinsicCache, getCurrentHeightIntrinsicCache] = createCache({
_initialValue: false,
});
const triggerOnTrinsicChangedCallback = (
updateValue?: IntersectionObserverEntry | WH<number>
) => {
if (updateValue) {
const heightIntrinsic = updateHeightIntrinsicCache(isHeightIntrinsic(updateValue));
const [, heightIntrinsicChanged] = heightIntrinsic;
if (heightIntrinsicChanged) {
onTrinsicChangedCallback(heightIntrinsic);
}
}
};
if (IntersectionObserverConstructor) {
const intersectionObserverInstance: IntersectionObserver = new IntersectionObserverConstructor(
(entries: IntersectionObserverEntry[]) => {
if (entries && entries.length > 0) {
triggerOnTrinsicChangedCallback(entries.pop());
}
},
{ root: target }
);
intersectionObserverInstance.observe(trinsicObserver);
push(offListeners, () => {
intersectionObserverInstance.disconnect();
});
} else {
const onSizeChanged = () => {
const newSize = offsetSize(trinsicObserver);
triggerOnTrinsicChangedCallback(newSize);
};
push(offListeners, createSizeObserver(trinsicObserver, onSizeChanged)._destroy);
onSizeChanged();
}
prependChildren(target, trinsicObserver);
return {
_destroy() {
runEach(offListeners);
removeElements(trinsicObserver);
},
_getCurrentCacheValues(force?: boolean) {
return {
_heightIntrinsic: getCurrentHeightIntrinsicCache(force),
};
},
};
};
|