// #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 = '[Dom] The host element does not exist';
            throw new Error(exceptionMessage);
        }
        return host;
    }
    findAncestor(element, selector, options) {
        const selectors = this.normalizeSelector(selector);
        const ancestor = element.closest(selectors);
        if (options?.strict && !ancestor) {
            const exceptionMessage = `[Dom] The ancestor element (${selectors}) does not exist.`;
            throw new Error(exceptionMessage);
        }
        return ancestor;
    }
    findDescendant(element, selector, options) {
        let descendant = null;
        const selectors = this.normalizeSelector(selector);
        descendant = element.querySelector(selectors);
        if (options?.strict && !descendant) {
            const exceptionMessage = `[Dom] The descendant element (${selectors}) does not exist.`;
            throw new Error(exceptionMessage);
        }
        return descendant;
    }
    findDescendants(element, selector, options) {
        let descendants = null;
        const selectors = this.normalizeSelector(selector);
        descendants = element.querySelectorAll(selectors);
        if (options?.strict && !descendants.length) {
            const exceptionMessage = `[Dom] The descendant elements (${selectors}) does not exist.`;
            throw new Error(exceptionMessage);
        }
        return [].slice.call(descendants);
    }
    /**
     * @private
     */
    normalizeSelector(selector) {
        if (typeof selector === 'string') {
            return selector;
        }
        else {
            if (isElement(selector)) {
                return selector.is;
            }
            else {
                return selector.tagName.toLowerCase();
            }
        }
    }
}
/**
 * @public
 */
export class DomServiceLocator {
    // #region Fields
    static _current = null;
    // #endregion
    // #region Properties
    static get current() {
        if (!DomServiceLocator.isSet()) {
            throw new Error('[DomServiceLocator] \'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