/**
* @module getClosest
* @description Gets the closest ancestor that matches a selector string starting from
* the passed HTMLElement.
*
* @since 1.0.0
*
* @param {HTMLElement} el The element to search upwards from.
* @param {string} selector The selector string to search for.
*
* @return {HTMLElement|null} An HTMLElement of null if not matching parent found.
*
* @example
* import { getClosest } from "@gravityforms/utils";
*
* function Example() {
* const node = document.getElementById( 'example' );
* const ancestor = getClosest( node, '.some-example-ancestor' );
* }
*
*/
export default function getClosest( el, selector ) {
let matchesFn;
let parent;
[
'matches',
'webkitMatchesSelector',
'mozMatchesSelector',
'msMatchesSelector',
'oMatchesSelector',
].some( ( fn ) => {
if ( typeof document.body[ fn ] === 'function' ) {
matchesFn = fn;
return true;
}
/* istanbul ignore next */
return false;
} );
while ( el ) {
parent = el.parentElement;
if ( parent && parent[ matchesFn ]( selector ) ) {
return parent;
}
el = parent; // eslint-disable-line
}
return null;
}