<commit_before>import Mmenu from '../oncanvas/mmenu.oncanvas';
import options from './_options';
import { extendShorthandOptions } from './_options';
import * as DOM from '../../_modules/dom';
import { extend } from '../../_modules/helpers';

//  Add the options.
Mmenu.options.keyboardNavigation = options;

export default function (this: Mmenu) {

    const options = extendShorthandOptions(this.opts.keyboardNavigation);
    this.opts.keyboardNavigation = extend(options, Mmenu.options.keyboardNavigation);

    if (!this.opts.keyboardNavigation.enable) {
        return;
    }

    // todo alleen bij off-canvas?

    //  Add tabindex="-1" to the menu and blocker so they can be focussed.
    this.bind('initMenu:after', () => {
        this.node.menu.setAttribute('tabindex', '-1');
        Mmenu.node.blck.setAttribute('tabindex', '-1');
    });

    //	Add tabindex="-1" to the page so it can be focussed.
    this.bind('setPage:after', () => {
        Mmenu.node.page.setAttribute('tabindex', '-1');
    });

    //  Focus menu when opening it.
    this.bind('open:after', () => {
        this.node.menu.focus();
    });

    //  Focus menu-button or page when closing the menu.
    this.bind('close:after', () => {
        let focus = document.querySelector(`[href="#${this.node.menu.id}"]`) || this.node.page;
        (focus as HTMLElement).focus();
    });

    //  Focus menu when opening panel.
    this.bind('openPanel:after', () => {
        this.node.menu.focus();
    });

    //  Prevent tabbing outside the menu.
    //      1) If the menu is opened
    //      2) and the focus is not inside the menu
    //      3) and the focus is not inside the blocker:
    //      4) Set focus to the blocker
    document.addEventListener('focusin', evnt => {

        if (this.node.menu.matches('.mm-menu--opened')) { // 1
            if (!(evnt.target as HTMLElement)?.closest(`#${this.node.menu.id}`) && // 2
                !(evnt.target as HTMLElement)?.closest(`#${Mmenu.node.blck.id}`) // 3
            ) {
                Mmenu.node.blck.focus(); // 4
            }
        }
    });

    //  Enhanced behavior
    if (this.opts.keyboardNavigation.enhance) {

        //  Add :hover like styles for :focus
        this.bind('initMenu:after', () => {
            this.node.menu.classList.add('mm-menu--keyboardfocus');
        });

        //	Add Additional keyboard behavior.
        this.node.menu.addEventListener('keydown', (evnt: KeyboardEvent) => {

            switch (evnt.key) {
                //	close submenu with backspace
                case 'Backspace':
                    const panel: HTMLElement = DOM.find(
                        this.node.pnls,
                        '.mm-panel--opened'
                    )[0];

                    if (panel) {
                        this.closePanel(panel);
                    }
                    break;

                //	close menu with esc<commit_msg>keyboard navigation<commit_after>import Mmenu from '../oncanvas/mmenu.oncanvas';
import options from './_options';
import { extendShorthandOptions } from './_options';
import * as DOM from '../../_modules/dom';
import { extend } from '../../_modules/helpers';

//  Add the options.
Mmenu.options.keyboardNavigation = options;

export default function (this: Mmenu) {

    const options = extendShorthandOptions(this.opts.keyboardNavigation);
    this.opts.keyboardNavigation = extend(options, Mmenu.options.keyboardNavigation);

    if (!this.opts.keyboardNavigation.enable) {
        return;
    }

    // todo alleen bij off-canvas?

    //  Add tabindex="-1" to the menu and blocker so they can be focussed.
    this.bind('initMenu:after', () => {
        this.node.menu.setAttribute('tabindex', '-1');
        Mmenu.node.blck.setAttribute('tabindex', '-1');
    });

    //	Add tabindex="-1" to the page so it can be focussed.
    this.bind('setPage:after', () => {
        Mmenu.node.page.setAttribute('tabindex', '-1');
    });

    //  Focus menu when opening it.
    this.bind('open:after', () => {
        this.node.menu.focus();
    });

    //  Focus menu-button or page when closing the menu.
    this.bind('close:after', () => {
        let focus = document.querySelector(`[href="#${this.node.menu.id}"]`) || this.node.page;
        (focus as HTMLElement).focus();
    });

    //  Focus menu when opening panel.
    this.bind('openPanel:after', () => {
        this.node.menu.focus();
    });

    //  Prevent tabbing outside the menu.
    //      1) If the menu is opened
    //      2) and the focus is not inside the menu
    //      3) and the focus is not inside the blocker:
    //      4) Set focus to the blocker
    document.addEventListener('focusin', evnt => {

        if (this.node.menu.matches('.mm-menu--opened')) { // 1
            if (!(evnt.target as HTMLElement)?.closest(`#${this.node.menu.id}`) && // 2
                !(evnt.target as HTMLElement)?.closest(`#${Mmenu.node.blck.id}`) // 3
            ) {
                Mmenu.node.blck.focus(); // 4
            }
        }
    });

    //	Add Additional keyboard behavior.
    if (this.opts.keyboardNavigation.enhance) {

        this.node.menu.addEventListener('keydown', (evnt: KeyboardEvent) => {

            switch (evnt.key) {
                //	close submenu with backspace
                case 'Backspace':
                    const panel: HTMLElement = DOM.find(
                        this.node.pnls,
                        '.mm-panel--opened'
                    )[0];

                    if (panel) {
                        this.closePanel(panel);
                    }
                    break;

                //	close menu with esc
{'fraction_non_alphanumeric': 0.15053763440860216, 'fraction_numerical': 0.004935660144544333, 'mean_word_length': 1.8671045982819605, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, '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': '4150019', 'n_tokens_mistral': 1699, 'n_tokens_neox': 1636, 'n_words': 384}