public function getEditorInitJSFunction($dynamicOptions = [])
    {
        $pluginManager = $this->getPluginManager();

        if ($this->allowFileManager()) {
            $pluginManager->select(['concrete5filemanager', 'concrete5uploadimage']);
        } else {
            $pluginManager->deselect(['concrete5filemanager', 'concrete5uploadimage']);
        }

        $this->requireEditorAssets();
        $plugins = $pluginManager->getSelectedPlugins();
        $snippetsAndClasses = $this->getEditorSnippetsAndClasses();

        if (!is_array($dynamicOptions)) {
            $dynamicOptions = [];
        }

        $defaultOptions = [
            'plugins' => implode(',', $plugins),
            'stylesSet' => 'concrete5styles',
            'filebrowserBrowseUrl' => 'a',
            'uploadUrl' => (string) URL::to('/ccm/system/file/upload'),
            'language' => $this->getLanguageOption(),
            'customConfig' => '',
            'allowedContent' => true,
            'baseFloatZIndex' => 1990, /* Must come below modal variable in variables.less */
            'image2_captionedClass' => 'content-editor-image-captioned',
            'image2_alignClasses' => [
                'content-editor-image-left',
                'content-editor-image-center',
                'content-editor-image-right',
            ],
            'toolbarGroups' => $this->config->get('editor.ckeditor4.toolbar_groups'),
            'snippets' => $snippetsAndClasses->snippets,
            'classes' => $snippetsAndClasses->classes,
            'sitemap' => $this->allowSitemap()
        ];

        $customOptions = $this->config->get('editor.ckeditor4.custom_config_options');
        if (!is_array($customOptions)) {
            $customOptions = [];
        }

        $options = json_encode($dynamicOptions + $customOptions + $defaultOptions);
        $removeEmptyIcon = '$removeEmpty[\'i\']';

        $jsfunc = <<<EOL
        function(identifier) {
            window.CCM_EDITOR_SECURITY_TOKEN = "{$this->token}";
            CKEDITOR.dtd.{$removeEmptyIcon} = false;
            if (CKEDITOR.stylesSet.get('concrete5styles') === null) {
                CKEDITOR.stylesSet.add('concrete5styles', {$this->getStylesJson()});
            }
            var ckeditor = $(identifier).ckeditor({$options}).editor;
            ckeditor.on('blur',function(){
                return false;
            });
            ckeditor.on('remove', function(){
                $(this).destroy();
            });
            if (CKEDITOR.env.ie) {
                ckeditor.on('ariaWidget', function (e) {
                    setTimeout(function() {
                        var \$contents = $(e.editor.ui.contentsElement.$),
                            \$textarea = \$contents.find('>textarea.cke_source');
                        if (\$textarea.length === 1) {
                            \$textarea.css({
                                width: \$contents.innerWidth() + 'px',
                                height: \$contents.innerHeight() + 'px'
                            });
                        }
                    }, 50);
                });
            }
            {$this->config->get('editor.ckeditor4.editor_function_options')}
        }
EOL;

        return $jsfunc;
    }