Source: plot/core/utils/PlotlyNotifier.js

export { PlotlyNotifier }

/**
 * Class to simulate plotly's notification function and write own notification messages.
 * Required because it is not accessible from outside.
 */
class PlotlyNotifier {
    /**
     * Creates the default plotly notification container if it does not already exist and then returns it.
     * @returns {HTMLDivElement} - Notification container.
     */
    static getPlotlyNotificationContainer() {
        let targetNode = document.body.querySelector('.plotly-notifier')
        if (!targetNode) {
            const defaultPlotlyNotifierElement = document.createElement('div');
            defaultPlotlyNotifierElement.classList.add('plotly-notifier');
            document.body.append(defaultPlotlyNotifierElement);
            targetNode = defaultPlotlyNotifierElement;
        }
        return targetNode
    }

    /**
     * Create the default plotly notification element containing the notification message.
     * @param {String} message - Message text.
     * @returns {HTMLDivElement} - Notification element.
     */
    static _createNotification(message) {
        const notifierNote = document.createElement('div');
        notifierNote.classList.add('notifier-note', 'notifier-note-custom', 'open');
        notifierNote.innerHTML = `
            <button class="notifier-close">×</button>
            <p>
                <span>${message}</span>
            </p>
            `;
        return notifierNote
    }

    /**
     * Displays a custom message in Plotly's default DOM node.
     * @param {String} message - Message text.
     * @param {Number} duration - How long the message should be displayed.
     */
    static displayMessage(message, duration) {
        const notifierContainer = PlotlyNotifier.getPlotlyNotificationContainer();
        const notifierNote = PlotlyNotifier._createNotification(message);
        notifierContainer.appendChild(notifierNote);

        const removeNotification = () => {
            notifierNote.classList.replace('open', 'closed');
            setTimeout(() => {
                notifierNote.remove();
                if (notifierContainer.childElementCount == 0 && !notifierContainer.classList.contains('observed')) {
                    notifierContainer.remove()
                }
            }, 700);
        }
        notifierNote.querySelector(".notifier-close").addEventListener("click", removeNotification);
        setTimeout(removeNotification, duration);
    }
}