<commit_before>import {off, on} from "./dom/events";
import {isChildElement} from "./dom/traverse";


/**
 * Registers a body click handler, that will trigger for any click in the body.
 * You can define allowed click targets, where the handler will not be called for.
 *
 * Returns a callback to remove the listener.
 */
export function registerBodyClickHandler (allowedClickTargets: HTMLElement[], onInvalidTargetClick: () => void) : () => void
{
    let handler = (event: Event) => {
        for (let i = 0; i < allowedClickTargets.length; i++)
        {
            // if the click is in any of the allowed containers -> do nothing
            if (isChildElement(allowedClickTargets[i], event.target as Node))
            {
                return;
            }
        }

        // click is outside of allowed containers -> callback
        onInvalidTargetClick();
    };

    on(document.body, "click", handler);

    return () => {
        off(document.body, "click", handler);
    };
}


/**
 * Initializes the complete interaction for a dismissable container.
 * The trigger opens the container.
 *
 * Returns a close function, with which you can close the container.
 * The close function has a property `.destroy`, which is a function that destroys the dismissable container
 */
export function initDismissableContainer (trigger: HTMLElement|HTMLElement[], allowedContainers: HTMLElement[], callback: (isActive: boolean) => void) : () => void
{
    let globalHandler: (() => void)|null = null;
    const triggers = Array.isArray(trigger) ? trigger : [trigger];

    const close = () =>
    {
        if (globalHandler)
        {
            globalHandler();
            globalHandler = null;
        }

        callback(false);
    };

    const open = () =>
    {
        if (globalHandler)
        {
            return;
        }

        globalHandler = registerBodyClickHandler(triggers.concat(allowedContainers), close);
        callback(true);
    };

    const eventListener = () => {<commit_msg>Properly type return value of initDismissableContainer<commit_after>import {off, on} from "./dom/events";
import {isChildElement} from "./dom/traverse";


/**
 * Registers a body click handler, that will trigger for any click in the body.
 * You can define allowed click targets, where the handler will not be called for.
 *
 * Returns a callback to remove the listener.
 */
export function registerBodyClickHandler (allowedClickTargets: HTMLElement[], onInvalidTargetClick: () => void) : () => void
{
    let handler = (event: Event) => {
        for (let i = 0; i < allowedClickTargets.length; i++)
        {
            // if the click is in any of the allowed containers -> do nothing
            if (isChildElement(allowedClickTargets[i], event.target as Node))
            {
                return;
            }
        }

        // click is outside of allowed containers -> callback
        onInvalidTargetClick();
    };

    on(document.body, "click", handler);

    return () => {
        off(document.body, "click", handler);
    };
}


type DismissableContainerReturn = {
    (): void;
    destroy(): void;
}

/**
 * Initializes the complete interaction for a dismissable container.
 * The trigger opens the container.
 *
 * Returns a close function, with which you can close the container.
 * The close function has a property `.destroy`, which is a function that destroys the dismissable container
 */
export function initDismissableContainer (trigger: HTMLElement|HTMLElement[], allowedContainers: HTMLElement[], callback: (isActive: boolean) => void) : DismissableContainerReturn
{
    let globalHandler: (() => void)|null = null;
    const triggers = Array.isArray(trigger) ? trigger : [trigger];

    const close = () =>
    {
        if (globalHandler)
        {
            globalHandler();
            globalHandler = null;
        }

        callback(false);
    };

    const open = () =>
    {
        if (globalHandler)
        {
            return;
        }

        globalHandler = registerBodyClickHandler(triggers.concat(allowedContainers), close);
        callback(true);
    };

    const eventListener = () => {
{'fraction_non_alphanumeric': 0.11079067531843306, 'fraction_numerical': 0.0004806536890170632, 'mean_word_length': 2.5694682675814753, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6677866', 'n_tokens_mistral': 1094, 'n_tokens_neox': 1078, 'n_words': 362}