/**
 * FILE:  ckeditor_setup.js
 *
 * Part of the Metavus digital collections platform
 * Copyright 2012-2024 Edward Almasy and Internet Scout Research Group
 * http://scout.wisc.edu
 * @scout:eslint
 */

/* global CKEDITOR */

(function(){
    var css = [];

    // can't continue if the CKEDITOR variable isn't available
    if (typeof CKEDITOR === "undefined") {
        return;
    }

    CKEDITOR.config.extraPlugins='justify,markdown';

    // hand the array of CSS files to CKEditor
    CKEDITOR.config.contentsCss = css;

    // create the default toolbar
    CKEDITOR.config.toolbar_CwisDefault = [
        ['Styles'],
        ['RemoveFormat'],
        ['Bold', 'Italic', 'Underline', 'Superscript', 'Subscript', 'Strike'],
        ['NumberedList', 'BulletedList', 'Blockquote'],
        ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
        ['Source'],
        ['Maximize'],
        '/',
        ['Undo', 'Redo'],
        ['Cut', 'Copy', '-', 'Paste', 'PasteText'],
        ['Find', 'Replace', '-', 'SpellChecker'],
        ['Link', 'Unlink', 'Anchor'],
        ['HorizontalRule', 'SpecialChar'],
        ['ShowBlocks', 'CreateDiv']
    ];

    // create the full toolbar, which requires style attributes and image tags
    CKEDITOR.config.toolbar_CwisFull = [
        ['Styles'],
        ['RemoveFormat'],
        ['Bold', 'Italic', 'Underline', 'Superscript', 'Subscript', 'Strike'],
        ['NumberedList', 'BulletedList', 'Blockquote'],
        ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'Indent', 'Outdent'],
        ['Source', 'Markdown'],
        ['Maximize'],
        '/',
        ['Undo', 'Redo'],
        ['Cut', 'Copy', '-', 'Paste', 'PasteText'],
        ['Find', 'Replace', '-', 'SpellChecker'],
        ['Link', 'Unlink', 'Anchor'],
        ['Image', 'Table'],
        ['HorizontalRule', 'SpecialChar'],
        ['TextColor', 'BGColor'],
        ['ShowBlocks', 'CreateDiv']
    ];

    // create a more limited inline editing toolbar
    CKEDITOR.config.toolbar_CwisInline = [
        ['Styles'],
        ['RemoveFormat'],
        ['Bold', 'Italic', 'Underline', 'Superscript', 'Subscript'],
        ['NumberedList', 'BulletedList'],
        ['JustifyLeft', 'JustifyCenter', 'JustifyRight'],
        ['Link', 'Unlink', 'Anchor'],
        '/',
        ['Find', 'Replace', '-', 'SpellChecker'],
        ['ShowBlocks', 'CreateDiv']
    ];

    // set the styles used by the styles button
    CKEDITOR.config.stylesSet = [
    // block styles
        {"name": "Paragraph", "element": "p"},
        {"name": "Heading 2", "element": "h2"},
        {"name": "Heading 3", "element": "h3"},
        {"name": "Heading 4", "element": "h4"},
        {"name": "Heading 5", "element": "h5"},
        {"name": "Heading 6", "element": "h6"},
        {"name": "Preformatted Text", "element": "pre"},

        // inline styles
        {"name": "Computer Code", "element": "code"}
    ];

    // use the default toolbar
    CKEDITOR.config.toolbar = "CwisDefault";

    // enable SCAYT by default
    CKEDITOR.config.scayt_autoStartup = true;

    // set up entity encoding/decoding
    CKEDITOR.config.entities = true;
    CKEDITOR.config.basicEntities = true;
    CKEDITOR.config.entities_greek = false;
    CKEDITOR.config.entitites_latin = false;
    CKEDITOR.config.entities_additional = '';

    /* eslint-enable no-undef */

    // configure content filtering to disallow problematic elements
    // generated by Word that aren't caught by the Paste From Word filter
    // see https://ckeditor.com/docs/ckeditor4/latest/guide/dev_disallowed_content.html
    // and https://ckeditor.com/docs/ckeditor4/latest/guide/dev_allowed_content_rules.html

    // disallowed content rules are processed first, in order
    // anything blocked by these is not seen by the allowedContent rules
    CKEDITOR.config.disallowedContent = {
        // delete all styles from spans, but leave attributes and classes alone
        span: {
            styles: true,
            attributes: false,
            classes: false
        },
        // remove any spans that have no remaining attrs, styles, or classes
        $1: {
            elements: ['span'],
            match: function (element) {
                if (Object.entries(element.attributes).length == 0 &&
                    Object.entries(element.styles).length == 0 &&
                    element.classes.length == 0) {
                    return true;
                }
                return false;
            },
        }
        // everything remaining is passed along to the allowedContent rules
    };

    // allowedContent rules are processed next, in order
    CKEDITOR.config.allowedContent = {
        $1: {
            elements: CKEDITOR.dtd,
            attributes: true,
            classes: true,
            styles: [
                'clear'
            ]
        }
    };

    // in Markdown mode, enable line wrapping
    CKEDITOR.config.markdown = {
        lineWrapping: true
    };

    // set the dir attribute to auto
    CKEDITOR.config.contentsLangDirection = 'auto';

    // set custom toolbar for inline editors
    CKEDITOR.on('instanceCreated', function(event) {
        var editor = event.editor;
        if (editor.name.indexOf('mv-inline') != -1) {
            editor.config.toolbar = "CwisInline";
            editor.config.stylesSet = [
                // block styles
                {"name": "Paragraph", "element": "p"},
                {"name": "Heading 2", "element": "h2"},
                {"name": "Heading 3", "element": "h3"}
            ];
        }
    });

}());
