@jupyterlab/application
Version: 
JupyterLab - Application
140 lines • 5.9 kB
JavaScript
/*
 * Copyright (c) Jupyter Development Team.
 * Distributed under the terms of the Modified BSD License.
 */
import { nullTranslator } from '@jupyterlab/translation';
/**
 * Add a semantic commands to the application and take care
 * of setting up the command changed signal.
 *
 * @param options Semantic command options
 */
export function addSemanticCommand(options) {
    const { id, commands, shell, semanticCommands, default: defaultValues, overrides, trans } = options;
    commands.addCommand(id, {
        ...createSemanticCommand({ commands, shell }, semanticCommands, defaultValues !== null && defaultValues !== void 0 ? defaultValues : {}, trans !== null && trans !== void 0 ? trans : nullTranslator.load('jupyterlab')),
        ...overrides
    });
    const commandList = Array.isArray(semanticCommands)
        ? semanticCommands
        : [semanticCommands];
    const onCommandChanged = (commands, args) => {
        if (args.id) {
            if (args.id === id && args.type === 'removed') {
                commands.commandChanged.disconnect(onCommandChanged);
            }
            else {
                const commandIds = commandList.reduce((agg, cmd) => agg.concat(cmd.ids), []);
                if (commandIds.includes(args.id)) {
                    switch (args.type) {
                        case 'changed':
                        case 'many-changed':
                            commands.notifyCommandChanged(id);
                            break;
                        case 'removed':
                            for (const cmd of commandList) {
                                cmd.remove(args.id);
                            }
                            break;
                    }
                }
            }
        }
    };
    commands.commandChanged.connect(onCommandChanged);
}
/**
 * Create the command options from the given semantic commands list
 * and the given default values.
 *
 * @param app Jupyter Application
 * @param semanticCommands Single semantic command  or a list of commands
 * @param defaultValues Default values
 * @param trans Translation bundle
 * @returns Command options
 *
 * @deprecated Please use {@link addSemanticCommand}. This function will
 * be removed of the public API in JupyterLab 5.
 */
export function createSemanticCommand(app, semanticCommands, defaultValues, trans) {
    const { commands, shell } = app;
    const commandList = Array.isArray(semanticCommands)
        ? semanticCommands
        : [semanticCommands];
    return {
        label: concatenateTexts('label'),
        caption: concatenateTexts('caption'),
        isEnabled: () => {
            var _a;
            const isEnabled = reduceAttribute('isEnabled');
            return ((isEnabled.length > 0 &&
                !isEnabled.some(enabled => enabled === false)) ||
                ((_a = defaultValues.isEnabled) !== null && _a !== void 0 ? _a : false));
        },
        isToggled: () => {
            var _a;
            const isToggled = reduceAttribute('isToggled');
            return (isToggled.some(enabled => enabled === true) ||
                ((_a = defaultValues.isToggled) !== null && _a !== void 0 ? _a : false));
        },
        isVisible: () => {
            var _a;
            const isVisible = reduceAttribute('isVisible');
            return ((isVisible.length > 0 &&
                !isVisible.some(visible => visible === false)) ||
                ((_a = defaultValues.isVisible) !== null && _a !== void 0 ? _a : true));
        },
        execute: async () => {
            const widget = shell.currentWidget;
            const commandIds = commandList.map(cmd => widget !== null ? cmd.getActiveCommandId(widget) : null);
            const toExecute = commandIds.filter(commandId => commandId !== null && commands.isEnabled(commandId));
            let result = null;
            if (toExecute.length > 0) {
                for (const commandId of toExecute) {
                    result = await commands.execute(commandId);
                    if (typeof result === 'boolean' && result === false) {
                        // If a command returns a boolean, assume it is the execution success status
                        // So break if it is false.
                        break;
                    }
                }
            }
            else if (defaultValues.execute) {
                result = await commands.execute(defaultValues.execute);
            }
            return result;
        }
    };
    function reduceAttribute(attribute) {
        const widget = shell.currentWidget;
        const commandIds = commandList.map(cmd => widget !== null ? cmd.getActiveCommandId(widget) : null);
        const attributes = commandIds
            .filter(commandId => commandId !== null)
            .map(commandId => commands[attribute](commandId));
        return attributes;
    }
    function concatenateTexts(attribute) {
        return () => {
            var _a;
            const texts = reduceAttribute(attribute).map((text, textIndex) => attribute == 'caption' && textIndex > 0
                ? text.toLocaleLowerCase()
                : text);
            switch (texts.length) {
                case 0:
                    return (_a = defaultValues[attribute]) !== null && _a !== void 0 ? _a : '';
                case 1:
                    return texts[0];
                default: {
                    const hasEllipsis = texts.some(l => /…$/.test(l));
                    const main = texts
                        .slice(undefined, -1)
                        .map(l => l.replace(/…$/, ''))
                        .join(', ');
                    const end = texts.slice(-1)[0].replace(/…$/, '') + (hasEllipsis ? '…' : '');
                    return trans.__('%1 and %2', main, end);
                }
            }
        };
    }
}
//# sourceMappingURL=utils.js.map