UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

75 lines (72 loc) 3.04 kB
// 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 }; };