/**
 * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module ui/editorui/accessibilityhelp/accessibilityhelp
 */
import { Plugin } from '@ckeditor/ckeditor5-core';
import ButtonView from '../../button/buttonview.js';
import Dialog from '../../dialog/dialog.js';
import MenuBarMenuListItemButtonView from '../../menubar/menubarmenulistitembuttonview.js';
import AccessibilityHelpContentView from './accessibilityhelpcontentview.js';
import { getEnvKeystrokeText } from '@ckeditor/ckeditor5-utils';
import accessibilityIcon from '../../../theme/icons/accessibility.svg';
import '../../../theme/components/editorui/accessibilityhelp.css';
/**
 * A plugin that brings the accessibility help dialog to the editor available under the <kbd>Alt</kbd>+<kbd>0</kbd>
 * keystroke and via the "Accessibility help" toolbar button. The dialog displays a list of keystrokes that can be used
 * by the user to perform various actions in the editor.
 *
 * Keystroke information is loaded from {@link module:core/accessibility~Accessibility#keystrokeInfos}. New entries can be
 * added using the API provided by the {@link module:core/accessibility~Accessibility} class.
 */
export default class AccessibilityHelp extends Plugin {
    constructor() {
        super(...arguments);
        /**
         * The view that displays the dialog content (list of keystrokes).
         * Created when the dialog is opened for the first time.
         */
        this.contentView = null;
    }
    /**
     * @inheritDoc
     */
    static get requires() {
        return [Dialog];
    }
    /**
     * @inheritDoc
     */
    static get pluginName() {
        return 'AccessibilityHelp';
    }
    /**
     * @inheritDoc
     */
    init() {
        const editor = this.editor;
        const t = editor.locale.t;
        editor.ui.componentFactory.add('accessibilityHelp', () => {
            const button = this._createButton(ButtonView);
            button.set({
                tooltip: true,
                withText: false,
                label: t('Accessibility help')
            });
            return button;
        });
        editor.ui.componentFactory.add('menuBar:accessibilityHelp', () => {
            const button = this._createButton(MenuBarMenuListItemButtonView);
            button.label = t('Accessibility');
            return button;
        });
        editor.keystrokes.set('Alt+0', (evt, cancel) => {
            this._toggleDialog();
            cancel();
        });
        this._setupRootLabels();
    }
    /**
     * Creates a button to show accessibility help dialog, for use either in toolbar or in menu bar.
     */
    _createButton(ButtonClass) {
        const editor = this.editor;
        const dialog = editor.plugins.get('Dialog');
        const locale = editor.locale;
        const view = new ButtonClass(locale);
        view.set({
            keystroke: 'Alt+0',
            icon: accessibilityIcon,
            isToggleable: true
        });
        view.on('execute', () => this._toggleDialog());
        view.bind('isOn').to(dialog, 'id', id => id === 'accessibilityHelp');
        return view;
    }
    /**
     * Injects a help text into each editing root's `aria-label` attribute allowing assistive technology users
     * to discover the availability of the Accessibility help dialog.
     */
    _setupRootLabels() {
        const editor = this.editor;
        const editingView = editor.editing.view;
        const t = editor.t;
        editor.ui.on('ready', () => {
            editingView.change(writer => {
                for (const root of editingView.document.roots) {
                    addAriaLabelTextToRoot(writer, root);
                }
            });
            editor.on('addRoot', (evt, modelRoot) => {
                const viewRoot = editor.editing.view.document.getRoot(modelRoot.rootName);
                editingView.change(writer => addAriaLabelTextToRoot(writer, viewRoot));
            }, { priority: 'low' });
        });
        function addAriaLabelTextToRoot(writer, viewRoot) {
            const currentAriaLabel = viewRoot.getAttribute('aria-label');
            const newAriaLabel = [currentAriaLabel, t('Press %0 for help.', [getEnvKeystrokeText('Alt+0')])]
                .filter(segment => segment)
                .join('. ');
            writer.setAttribute('aria-label', newAriaLabel, viewRoot);
        }
    }
    /**
     * Shows the accessibility help dialog. Also, creates {@link #contentView} on demand.
     */
    _toggleDialog() {
        const editor = this.editor;
        const dialog = editor.plugins.get('Dialog');
        const t = editor.locale.t;
        if (!this.contentView) {
            this.contentView = new AccessibilityHelpContentView(editor.locale, editor.accessibility.keystrokeInfos);
        }
        if (dialog.id === 'accessibilityHelp') {
            dialog.hide();
        }
        else {
            dialog.show({
                id: 'accessibilityHelp',
                className: 'ck-accessibility-help-dialog',
                title: t('Accessibility help'),
                icon: accessibilityIcon,
                hasCloseButton: true,
                content: this.contentView
            });
        }
    }
}
