/* -----------------------------------------------------------------------------
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
import { Token } from '@lumino/coreutils';
import { Panel, Widget } from '@lumino/widgets';
import { searchIcon } from '@jupyterlab/ui-components';
/* tslint:disable */
/**
 * The command palette token.
 */
export const ICommandPalette = new Token('@jupyterlab/apputils:ICommandPalette');
/**
 * Class name identifying the input group with search icon.
 */
const SEARCH_ICON_GROUP_CLASS = 'jp-SearchIconGroup';
/**
 * Wrap the command palette in a modal to make it more usable.
 */
export class ModalCommandPalette extends Panel {
    constructor(options) {
        super();
        this.addClass('jp-ModalCommandPalette');
        this.id = 'modal-command-palette';
        this.palette = options.commandPalette;
        this._commandPalette.commands.commandExecuted.connect(() => {
            if (this.isAttached && this.isVisible) {
                this.hideAndReset();
            }
        });
        // required to properly receive blur and focus events;
        // selection of items with mouse may not work without this.
        this.node.tabIndex = 0;
    }
    get palette() {
        return this._commandPalette;
    }
    set palette(value) {
        this._commandPalette = value;
        if (!this.searchIconGroup) {
            this._commandPalette.inputNode.insertAdjacentElement('afterend', this.createSearchIconGroup());
        }
        this.addWidget(value);
        this.hideAndReset();
    }
    attach() {
        Widget.attach(this, document.body);
    }
    detach() {
        Widget.detach(this);
    }
    /**
     * Hide the modal command palette and reset its search.
     */
    hideAndReset() {
        this.hide();
        this._commandPalette.inputNode.value = '';
        this._commandPalette.refresh();
    }
    /**
     * Handle incoming events.
     */
    handleEvent(event) {
        switch (event.type) {
            case 'keydown':
                this._evtKeydown(event);
                break;
            case 'blur': {
                // if the focus shifted outside of this DOM element, hide and reset.
                if (
                // focus went away from child element
                this.node.contains(event.target) &&
                    // and it did NOT go to another child element but someplace else
                    !this.node.contains(event.relatedTarget)) {
                    event.stopPropagation();
                    this.hideAndReset();
                }
                break;
            }
            case 'contextmenu':
                event.preventDefault();
                event.stopPropagation();
                break;
            default:
                break;
        }
    }
    /**
     * Find the element with search icon group.
     */
    get searchIconGroup() {
        return this._commandPalette.node.getElementsByClassName(SEARCH_ICON_GROUP_CLASS)[0];
    }
    /**
     * Create element with search icon group.
     */
    createSearchIconGroup() {
        const inputGroup = document.createElement('div');
        inputGroup.classList.add(SEARCH_ICON_GROUP_CLASS);
        searchIcon.render(inputGroup);
        return inputGroup;
    }
    /**
     *  A message handler invoked on an `'after-attach'` message.
     */
    onAfterAttach(msg) {
        this.node.addEventListener('keydown', this, true);
        this.node.addEventListener('contextmenu', this, true);
    }
    /**
     *  A message handler invoked on an `'after-detach'` message.
     */
    onAfterDetach(msg) {
        this.node.removeEventListener('keydown', this, true);
        this.node.removeEventListener('contextmenu', this, true);
    }
    onBeforeHide(msg) {
        document.removeEventListener('blur', this, true);
    }
    onAfterShow(msg) {
        document.addEventListener('blur', this, true);
    }
    /**
     * A message handler invoked on an `'activate-request'` message.
     */
    onActivateRequest(msg) {
        if (this.isAttached) {
            this.show();
            this._commandPalette.activate();
        }
    }
    /**
     * Handle the `'keydown'` event for the widget.
     */
    _evtKeydown(event) {
        // Check for escape key
        switch (event.keyCode) {
            case 27: // Escape.
                event.stopPropagation();
                event.preventDefault();
                this.hideAndReset();
                break;
            default:
                break;
        }
    }
}
//# sourceMappingURL=commandpalette.js.map