/** * External dependencies */ import type { CssSizeUnit } from '@nelio/popups/types'; export function addClass( el: Element | null ): void; export function addClass( className: string, el: Element | null ): void; export function addClass( className: string | Element | null, el?: Element | null ): void { if ( 'string' !== typeof className ) { el = className; className = 'nelio-popup'; } else { className = `nelio-popup-${ className }`; } if ( ! el ) { return; } el.classList.add( className ); } export function removeClass( el: Element | null ): void; export function removeClass( className: string, el: Element | null ): void; export function removeClass( className: string | Element | null, el?: Element | null ): void { if ( 'string' !== typeof className ) { el = className; className = 'nelio-popup'; } else { className = `nelio-popup-${ className }`; } if ( ! el ) { return; } el.classList.remove( className ); } export function hasClass( className: string, el?: Element | null ): boolean { return !! el && el.classList.contains( `nelio-popup-${ className }` ); } export function isCloseButton( context: HTMLElement, el: HTMLElement ): boolean { return ( el.getAttribute( 'href' ) === '#close-nelio-popup' || isElementInSelection( context, '.nelio-popup-js-close', el ) ); } export function isElementInSelection( context: Document | HTMLElement, selector: string, el?: HTMLElement | null ): boolean { if ( ! el ) { return false; } try { const els = Array.from( context.querySelectorAll( selector ) ); let node: HTMLElement | null = el; while ( node ) { if ( els.includes( node ) ) { return true; } node = node.parentElement; } return false; } catch ( _ ) { return false; } } // end isElementInSelection() export function cssUnitToPixels( el: HTMLElement, { unit, value }: CssSizeUnit ): number { switch ( unit ) { case 'px': return value; case '%': return Math.floor( ( value * getHeight( el ) ) / 100 ); case 'em': return value * getEmInPixels( el ); case 'rem': return value * getRemInPixels( el ); } } export const isHTMLElement = ( el: Element | null ): el is HTMLElement => !! el; // ======= // HELPERS // ======= function getHeight( el: Element ): number { const fn = () => `${ el.clientHeight }`; return parseInt( getData( el, 'height', fn ) ) || 0; } function getEmInPixels( el: Element ): number { const fn = () => { const aux = document.createElement( 'div' ); aux.style.height = '1em'; el.appendChild( aux ); const height = aux.clientHeight; el.removeChild( aux ); return `${ height }`; }; return parseInt( getData( el, 'em-size', fn ) ) || 0; } function getRemInPixels( el: Element ): number { const fn = () => { const aux = document.createElement( 'div' ); aux.style.height = '1rem'; el.appendChild( aux ); const height = aux.clientHeight; el.removeChild( aux ); return `${ height }`; }; return parseInt( getData( el, 'rem-size', fn ) ) || 0; } function getData( el: Element, name: string, compute: () => string ): string { if ( ! el.hasAttribute( `data-nelio-popups-${ name }` ) ) { const value = compute(); el.setAttribute( `data-nelio-popups-${ name }`, `${ value }` ); } return el.getAttribute( `data-nelio-popups-${ name }` ) || ''; }