@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
75 lines (72 loc) • 3.04 kB
JavaScript
// Use this selector to set the intersection observer boundary for editor's inline node views
// If this does not exist, it will use the IntersectionObserver's default root
var INTERSECTION_OBSERVER_ROOT_SELECTOR = '[data-editor-scroll-container="true"]';
var editorObservers = new WeakMap();
var callbackMap = new WeakMap();
/**
* Creates a node visibility manager
* @param editorElement
* @returns
*/
export var nodeVisibilityManager = function nodeVisibilityManager(editorElement) {
// Warning! do not reference editorElement outside of internal functions.
// editorElement is passed to allow support for multiple editors,
var unObserveInternal = function unObserveInternal(nodeElement) {
var _editorObservers$get;
(_editorObservers$get = editorObservers.get(editorElement)) === null || _editorObservers$get === void 0 || _editorObservers$get.unobserve(nodeElement);
callbackMap.delete(nodeElement);
};
var observe = function observe(observerConfig) {
var _editorObservers$get2;
callbackMap.set(observerConfig.element, observerConfig);
(_editorObservers$get2 = editorObservers.get(editorElement)) === null || _editorObservers$get2 === void 0 || _editorObservers$get2.observe(observerConfig.element);
// return clean up
return function () {
// consumer needs to unobserve on destroy if their element
// was observed but never scrolled into view
unObserveInternal(observerConfig.element);
};
};
var initialiseNodeObserver = function initialiseNodeObserver() {
if (editorObservers.has(editorElement)) {
return;
}
var intersectionObserverOptions = {
root: editorElement.closest(INTERSECTION_OBSERVER_ROOT_SELECTOR),
rootMargin: '0px 0px 100px 0px',
threshold: 0
};
var editorObserver = new IntersectionObserver(function (entries) {
return entries.map(function (entry) {
return {
entry: entry,
callback: callbackMap.get(entry.target)
};
})
// Invoke callbacks together to group browser rendering
// Avoiding requestAnimationFrame to reduce visual flickering
.forEach(function (_ref) {
var entry = _ref.entry,
callback = _ref.callback;
if (entry.isIntersecting) {
callback === null || callback === void 0 || callback.onFirstVisible();
if (entry.target instanceof HTMLElement) {
// immediately unobserve the element after it is visible
unObserveInternal(entry.target);
}
}
});
}, intersectionObserverOptions);
editorObservers.set(editorElement, editorObserver);
};
var disconnect = function disconnect() {
var _editorObservers$get3;
(_editorObservers$get3 = editorObservers.get(editorElement)) === null || _editorObservers$get3 === void 0 || _editorObservers$get3.disconnect();
editorObservers.delete(editorElement);
};
return {
initialiseNodeObserver: initialiseNodeObserver,
observe: observe,
disconnect: disconnect
};
};