diff --git a/packages/overlayscrollbars/src/lifecycles/lifecycleHub.ts b/packages/overlayscrollbars/src/lifecycles/lifecycleHub.ts index 6ac5b49..ac8d537 100644 --- a/packages/overlayscrollbars/src/lifecycles/lifecycleHub.ts +++ b/packages/overlayscrollbars/src/lifecycles/lifecycleHub.ts @@ -72,6 +72,7 @@ const emptyStylePropsToZero = (stlyeObj: StyleObject, baseStyle?: StyleObject) = { ...baseStyle } ); +// TODO: observer textarea attrs if textarea // TODO: tabindex, open etc. const attrs = ['id', 'class', 'style', 'open']; const paddingInfoFallback: PaddingInfo = { diff --git a/packages/overlayscrollbars/src/observers/domObserver.ts b/packages/overlayscrollbars/src/observers/domObserver.ts index e467d9d..42a7271 100644 --- a/packages/overlayscrollbars/src/observers/domObserver.ts +++ b/packages/overlayscrollbars/src/observers/domObserver.ts @@ -44,7 +44,7 @@ export interface DOMObserverOptions { _ignoreContentChange?: DOMObserverIgnoreContentChange; } export interface DOMObserver { - _disconnect: () => void; + _destroy: () => void; _updateEventContentChange: (newEventContentChange?: DOMObserverEventContentChange) => void; _update: () => void; } @@ -52,18 +52,21 @@ export interface DOMObserver { // const styleChangingAttributes = ['id', 'class', 'style', 'open']; // const mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows']; -const createEventContentChange = ( - target: Element, - eventContentChange: DOMObserverEventContentChange, - map: Map, - callback: (...args: any) => any -) => { +/** + * Creates a set of helper functions to observe events of elements inside the target element. + * @param target The target element of which the children elements shall be observed. (not only direct children but also nested ones) + * @param eventContentChange The event content change array. (array of tuples: selector and eventname(s)) + * @param callback Callback which is called if one of the elements emits the corresponding event. + * @returns A object which contains a set of helper functions to destroy and update the observation of elements. + */ +const createEventContentChange = (target: Element, eventContentChange: DOMObserverEventContentChange, callback: (...args: any) => any) => { + let map: Map | undefined; let eventContentChangeRef: DOMObserverEventContentChange; const addEvent = (elm: Node, eventName: string) => { - const entry = map.get(elm); + const entry = map!.get(elm); const newEntry = isUndefined(entry); const registerEvent = () => { - map.set(elm, eventName); + map!.set(elm, eventName); on(elm, eventName, callback); }; @@ -75,10 +78,10 @@ const createEventContentChange = ( } }; const _destroy = () => { - map.forEach((eventName: string, elm: Node) => { + map!.forEach((eventName: string, elm: Node) => { off(elm, eventName, callback); }); - map.clear(); + map!.clear(); }; const _updateElements = (getElements?: (selector: string) => Node[]) => { if (eventContentChangeRef) { @@ -105,23 +108,31 @@ const createEventContentChange = ( }); } }; - const _update = (newEventContentChange: DOMObserverEventContentChange) => { + const _updateEventContentChange = (newEventContentChange: DOMObserverEventContentChange) => { + map = map || new Map(); eventContentChangeRef = newEventContentChange; _destroy(); _updateElements(); }; if (eventContentChange) { - _update(eventContentChange); + _updateEventContentChange(eventContentChange); } return { _destroy, _updateElements, - _update, + _updateEventContentChange, }; }; +/** + * Creates a DOM observer which observes DOM changes to either the target element or its children. (not only direct children but also nested ones) + * @param target The element which shall be observed. + * @param callback The callback which gets called if a change was detected. + * @param options The options for DOM change detection. + * @returns A object which represents the instance of the DOM observer. + */ export const createDOMObserver = ( target: HTMLElement, callback: (targetChangedAttrs: string[], targetStyleChanged: boolean, contentChanged: boolean) => any, @@ -138,13 +149,12 @@ export const createDOMObserver = ( _ignoreContentChange, } = options || {}; const { - _updateElements: updateEventContentChangeElements, _destroy: destroyEventContentChange, - _update: updateEventContentChange, + _updateElements: updateEventContentChangeElements, + _updateEventContentChange: updateEventContentChange, } = createEventContentChange( target, _observeContent && _eventContentChange, - new Map(), debounce(() => { if (isConnected) { callback([], false, true); @@ -155,7 +165,7 @@ export const createDOMObserver = ( // MutationObserver const finalAttributes = _attributes || []; const finalStyleChangingAttributes = _styleChangingAttributes || []; - const observedAttributes = finalAttributes.concat(finalStyleChangingAttributes); // TODO: observer textarea attrs if textarea + const observedAttributes = finalAttributes.concat(finalStyleChangingAttributes); const observerCallback = (mutations: MutationRecord[]) => { const ignoreTargetChange = _ignoreTargetChange || noop; const ignoreContentChange = _ignoreContentChange || noop; @@ -199,6 +209,7 @@ export const createDOMObserver = ( }); if (childListChanged && !isEmptyArray(totalAddedNodes)) { + // adds / removes the new elements from the event content change updateEventContentChangeElements((selector) => totalAddedNodes.reduce((arr, node) => { push(arr, find(selector, node)); @@ -224,7 +235,7 @@ export const createDOMObserver = ( isConnected = true; return { - _disconnect: () => { + _destroy: () => { if (isConnected) { destroyEventContentChange(); mutationObserver.disconnect(); diff --git a/packages/overlayscrollbars/src/observers/sizeObserver.ts b/packages/overlayscrollbars/src/observers/sizeObserver.ts index d94c701..851c9e5 100644 --- a/packages/overlayscrollbars/src/observers/sizeObserver.ts +++ b/packages/overlayscrollbars/src/observers/sizeObserver.ts @@ -63,6 +63,13 @@ const scrollAmount = 3333333; const directionIsRTL = (elm: HTMLElement): boolean => style(elm, 'direction') === 'rtl'; const domRectHasDimensions = (rect?: DOMRectReadOnly) => rect && (rect.height || rect.width); +/** + * Creates a size observer which observes any size, padding, margin and border changes of the target element. Depending on the options also direction and appear can be observed. + * @param target The target element which shall be observed. + * @param onSizeChangedCallback The callback which gets called after a size change was detected. + * @param options The options for size detection, whether to observe also direction and appear. + * @returns A object which represents the instance of the size observer. + */ export const createSizeObserver = ( target: HTMLElement, onSizeChangedCallback: (directionIsRTLCache?: CacheValues) => any, diff --git a/packages/overlayscrollbars/src/observers/trinsicObserver.ts b/packages/overlayscrollbars/src/observers/trinsicObserver.ts index d57a631..f70d7de 100644 --- a/packages/overlayscrollbars/src/observers/trinsicObserver.ts +++ b/packages/overlayscrollbars/src/observers/trinsicObserver.ts @@ -22,6 +22,12 @@ export interface TrinsicObserver { }; } +/** + * 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) => any diff --git a/packages/overlayscrollbars/tests/browser/observers/trinsicObserver/index.html b/packages/overlayscrollbars/tests/browser/observers/trinsicObserver/index.html index f834fec..78ce281 100644 --- a/packages/overlayscrollbars/tests/browser/observers/trinsicObserver/index.html +++ b/packages/overlayscrollbars/tests/browser/observers/trinsicObserver/index.html @@ -1,6 +1,6 @@
- -
+ +