// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import { Signal } from '@lumino/signaling';
import { h } from '@lumino/virtualdom';
import { ContextMenu, Menu } from '@lumino/widgets';
import { LabIconStyle } from '../../style';
import { classes } from '../../utils';
import { caretRightIcon, checkIcon } from '../iconimports';
const submenuIcon = caretRightIcon.bindprops({
    stylesheet: 'menuItem'
});
/**
 * An object which implements a universal context menu.
 * Tweaked to use inline svg icons
 */
export class ContextMenuSvg extends ContextMenu {
    /**
     * Construct a new context menu.
     *
     * @param options - The options for initializing the menu.
     */
    constructor(options) {
        super(options);
        this._isDisposed = false;
        this._opened = new Signal(this);
        // override the vanilla .menu
        this.menu = new MenuSvg(options);
    }
    /**
     * Test whether the context menu is disposed.
     */
    get isDisposed() {
        return this._isDisposed;
    }
    /**
     * A signal fired when the context menu is opened.
     */
    get opened() {
        return this._opened;
    }
    /**
     * Dispose of the resources held by the context menu.
     */
    dispose() {
        if (this._isDisposed) {
            return;
        }
        this._isDisposed = true;
        this.menu.dispose();
        Signal.disconnectSender(this);
    }
    /**
     * Open the context menu in response to a `'contextmenu'` event.
     *
     * @param event - The `'contextmenu'` event of interest.
     *
     * @returns `true` if the menu was opened, or `false` if no items
     *   matched the event and the menu was not opened.
     *
     * #### Notes
     * This method will populate the context menu with items which match
     * the propagation path of the event, then open the menu at the mouse
     * position indicated by the event.
     */
    open(event) {
        if (this._isDisposed) {
            return false;
        }
        const hasItems = super.open(event);
        if (hasItems) {
            this._opened.emit();
        }
        return hasItems;
    }
}
/**
 * a widget which displays items as a canonical menu.
 * Tweaked to use inline svg icons
 */
export class MenuSvg extends Menu {
    /**
     * construct a new menu. Overrides the default renderer
     *
     * @param options - The options for initializing the tab bar.
     */
    constructor(options) {
        options.renderer = options.renderer || MenuSvg.defaultRenderer;
        super(options);
    }
    /**
     * insert a menu item into the menu at the specified index. Replaces the
     * default renderer for submenus
     *
     * @param index - The index at which to insert the item.
     *
     * @param options - The options for creating the menu item.
     *
     * @returns The menu item added to the menu.
     *
     * #### Notes
     * The index will be clamped to the bounds of the items.
     */
    insertItem(index, options) {
        if (options.submenu) {
            MenuSvg.overrideDefaultRenderer(options.submenu);
        }
        return super.insertItem(index, options);
    }
}
(function (MenuSvg) {
    function overrideDefaultRenderer(menu) {
        // override renderer, if needed
        if (menu.renderer === Menu.defaultRenderer) {
            // cast away readonly on menu.renderer
            menu.renderer = MenuSvg.defaultRenderer;
        }
        // ensure correct renderer on any submenus that get added in the future
        const originalInsertItem = menu.insertItem.bind(menu);
        menu.insertItem = (index, options) => {
            if (options.submenu) {
                MenuSvg.overrideDefaultRenderer(options.submenu);
            }
            return originalInsertItem(index, options);
        };
        // recurse through submenus
        for (const item of menu._items) {
            if (item.submenu) {
                overrideDefaultRenderer(item.submenu);
            }
        }
    }
    MenuSvg.overrideDefaultRenderer = overrideDefaultRenderer;
    /**
     * a modified implementation of the Menu Renderer
     */
    class Renderer extends Menu.Renderer {
        /**
         * Render the icon element for a menu item.
         *
         * @param data - The data to use for rendering the icon.
         *
         * @returns A virtual element representing the item icon.
         */
        renderIcon(data) {
            const className = this.createIconClass(data);
            if (data.item.isToggled) {
                // check mark icon takes precedence
                return h.div({ className }, checkIcon, data.item.iconLabel);
            }
            /* <DEPRECATED> */
            if (typeof data.item.icon === 'string') {
                return h.div({ className: classes(className, 'jp-Icon') }, data.item.iconLabel);
            }
            /* </DEPRECATED> */
            // if data.item.icon is undefined, it will be ignored
            return h.div({ className }, data.item.icon, data.item.iconLabel);
        }
        /**
         * Create the class name for the menu item icon.
         *
         * @param data - The data to use for the class name.
         *
         * @returns The full class name for the item icon.
         */
        createIconClass(data) {
            let name = 'lm-Menu-itemIcon';
            /* <DEPRECATED> */
            name += ' p-Menu-itemIcon';
            /* </DEPRECATED> */
            if (data.item.type === 'separator') {
                return classes(data.item.iconClass, name);
            }
            else {
                return classes(LabIconStyle.styleClass({ stylesheet: 'menuItem' }), data.item.iconClass, name);
            }
        }
        /**
         * Render the submenu icon element for a menu item.
         *
         * @param data - The data to use for rendering the submenu icon.
         *
         * @returns A virtual element representing the submenu icon.
         */
        renderSubmenu(data) {
            const className = 'lm-Menu-itemSubmenuIcon' +
                /* <DEPRECATED> */
                ' p-Menu-itemSubmenuIcon';
            /* </DEPRECATED> */
            if (data.item.type === 'submenu') {
                return h.div({ className }, submenuIcon);
            }
            else {
                return h.div({ className });
            }
        }
    }
    MenuSvg.Renderer = Renderer;
    MenuSvg.defaultRenderer = new Renderer();
})(MenuSvg || (MenuSvg = {}));
//# sourceMappingURL=menusvg.js.map