/* eslint-disable @typescript-eslint/no-duplicate-type-constituents */
// #region Imports
export function isElement(self) {
    return typeof self === 'function' && 'is' in self;
}
/**
 * The `Dom` class.
 *
 *
 * @public
 */
export class Dom {
    // #region Ctor
    /**
     * Constructs a new instance of the `Dom` class.
     *
     * @public
     */
    constructor() {
    }
    findShadowDomHost(element, options) {
        // Check if the element is slotted
        const slot = element.assignedSlot;
        let host = null;
        if (slot) {
            // Use getRootNode to access the shadow root
            const root = slot.getRootNode();
            if (root instanceof ShadowRoot) {
                // The host property of the ShadowRoot gives the shadow DOM host
                host = root.host;
            }
        }
        else {
            // Use getRootNode to access the shadow root
            const root = element.getRootNode();
            if (root instanceof ShadowRoot) {
                // The host property of the ShadowRoot gives the shadow DOM host
                host = root.host;
            }
        }
        if (options?.strict && !host) {
            const exceptionMessage = 'The host element does not exist';
            throw new Error(exceptionMessage);
        }
        return host;
    }
    findAncestor(element, selector, options) {
        const ancestor = typeof selector === 'string'
            ? element.closest(selector)
            : element.closest(selector.is);
        if (options?.strict && !ancestor) {
            const exceptionMessage = 'The ancestor element does not exist';
            throw new Error(exceptionMessage);
        }
        return ancestor;
    }
    findDescendant(element, selector, options) {
        let descendant = null;
        if (typeof selector === 'string') {
            descendant = element.querySelector(selector);
        }
        else {
            // eslint-disable-next-line no-lonely-if
            if (isElement(selector)) {
                descendant = element.querySelector(selector.is);
            }
            else {
                descendant = element.querySelector(selector.tagName.toLowerCase());
            }
        }
        if (options?.strict && !descendant) {
            const exceptionMessage = 'The descendant element does not exist.';
            throw new Error(exceptionMessage);
        }
        return descendant;
    }
    findDescendants(element, selector, options) {
        let descendants = null;
        if (typeof selector === 'string') {
            descendants = element.querySelectorAll(selector);
        }
        else {
            // eslint-disable-next-line no-lonely-if
            if (isElement(selector)) {
                descendants = element.querySelectorAll(selector.is);
            }
            else {
                descendants = element.querySelectorAll(selector.tagName.toLowerCase());
            }
        }
        if (options?.strict && !descendants.length) {
            const exceptionMessage = 'The descendant elements does not exist.';
            throw new Error(exceptionMessage);
        }
        return [].slice.call(descendants);
    }
}
/**
 * @public
 */
export class DomServiceLocator {
    // #region Fields
    static _current = null;
    // #endregion
    // #region Properties
    static get current() {
        if (!DomServiceLocator.isSet()) {
            throw new Error('\'Dom\' not set.');
        }
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        return DomServiceLocator._current;
    }
    // #endregion
    // #region Methods
    static isSet() {
        return DomServiceLocator._current !== null;
    }
    static set(current) {
        DomServiceLocator._current = current;
    }
}
/**
 * @public
 */
DomServiceLocator.set(new Dom());
//# sourceMappingURL=Dom.js.map