/*!
 * KoliBri - The accessible HTML-Standard
 */
'use strict';

var tslib_es6 = require('./tslib.es6-Cm0ytgPY.js');

const MAX_TIMEOUT_DURATION = 5000;
function waitForThemed(host) {
    return new Promise((resolve, reject) => {
        let timeoutId;
        const observer = new MutationObserver(() => {
            if (host.hasAttribute('data-themed')) {
                if (timeoutId) {
                    clearTimeout(timeoutId);
                }
                observer.disconnect();
                resolve();
            }
        });
        observer.observe(host, {
            attributes: true,
            attributeFilter: ['data-themed'],
        });
        if (host.hasAttribute('data-themed')) {
            observer.disconnect();
            resolve();
            return;
        }
        timeoutId = setTimeout(() => {
            observer.disconnect();
            reject(new Error('Timeout waiting for data-themed attribute'));
        }, MAX_TIMEOUT_DURATION);
    });
}

const MAX_CLICK_ATTEMPTS = 3;
async function delegateClick(host, callback) {
    try {
        if (!host.hasAttribute('data-themed')) {
            await waitForThemed(host);
        }
        await callback();
    }
    catch (_a) {
        throw new Error(`The interactive element inside the KoliBri web component could not be clicked. Try calling the click method on the web component after a short delay again.`);
    }
}
function isElementVisible(element) {
    if (!element)
        return false;
    const rect = element.getBoundingClientRect();
    return rect.width > 0 && rect.height > 0;
}
async function setClick(element) {
    let attempts = 0;
    do {
        if (element) {
            element.click();
        }
        await new Promise((r) => requestAnimationFrame(r));
        attempts++;
    } while (!isElementVisible(element) && attempts < MAX_CLICK_ATTEMPTS);
}

const MAX_FOCUS_ATTEMPTS = 10;
function waitForElementInViewport(element, timeoutMs = 2000) {
    return new Promise((resolve) => {
        let resolved = false;
        let observer;
        let removeScrollEndListener;
        const done = () => {
            if (resolved) {
                return;
            }
            resolved = true;
            clearTimeout(timeoutId);
            removeScrollEndListener === null || removeScrollEndListener === void 0 ? void 0 : removeScrollEndListener();
            removeScrollEndListener = undefined;
            observer === null || observer === void 0 ? void 0 : observer.disconnect();
            resolve();
        };
        const timeoutId = setTimeout(done, timeoutMs);
        if (typeof window !== 'undefined' && 'onscrollend' in window) {
            const handleScrollEnd = (event) => {
                const target = event.target;
                if (!(target instanceof Node) || !target.contains(element)) {
                    return;
                }
                done();
            };
            document.addEventListener('scrollend', handleScrollEnd, { capture: true });
            removeScrollEndListener = () => {
                document.removeEventListener('scrollend', handleScrollEnd, { capture: true });
            };
            return;
        }
        if (typeof IntersectionObserver === 'undefined') {
            done();
            return;
        }
        observer = new IntersectionObserver((entries) => {
            if (entries.some((entry) => entry.isIntersecting)) {
                done();
            }
        }, { threshold: 0 });
        observer.observe(element);
    });
}
async function delegateFocus(host, callback) {
    try {
        if (!host.hasAttribute('data-themed')) {
            await waitForThemed(host);
        }
        await callback();
    }
    catch (_a) {
        throw new Error(`The interactive element inside the KoliBri web component could not be focused. Try calling the focus method on the web component after a short delay again.`);
    }
}
function isActiveElement(element) {
    const root = element.getRootNode();
    if (root instanceof ShadowRoot) {
        return root.activeElement === element;
    }
    return document.activeElement === element;
}
const FOCUS_OPTIONS = {
    preventScroll: true,
};
async function setFocus(element, options) {
    if (!element) {
        return;
    }
    const _a = options !== null && options !== void 0 ? options : {}, { afterFocus } = _a, scrollOptions = tslib_es6.__rest(_a, ["afterFocus"]);
    const hasScrollOptions = options && ('behavior' in scrollOptions || 'block' in scrollOptions || 'inline' in scrollOptions);
    let attempts = 0;
    do {
        if (element) {
            element.focus(FOCUS_OPTIONS);
        }
        await new Promise((r) => requestAnimationFrame(r));
        attempts++;
    } while (!isActiveElement(element) && attempts < MAX_FOCUS_ATTEMPTS);
    const focused = isActiveElement(element);
    if (hasScrollOptions) {
        const scrollIntoViewOptions = Object.assign(Object.assign({}, scrollOptions), { behavior: scrollOptions.behavior });
        element.scrollIntoView(scrollIntoViewOptions);
    }
    if (afterFocus && focused) {
        if (hasScrollOptions && scrollOptions.behavior === 'smooth') {
            await waitForElementInViewport(element);
        }
        afterFocus();
    }
}

exports.delegateClick = delegateClick;
exports.delegateFocus = delegateFocus;
exports.setClick = setClick;
exports.setFocus = setFocus;
//# sourceMappingURL=element-focus-B4BhAkh_.js.map

//# sourceMappingURL=element-focus-B4BhAkh_.js.map