Search code examples
javascriptckeditorcopy-pastepasteckeditor4.x

Paste custom tag in CKeditor


In my Ckeditor (version 4.8) I have a custom citation tag like <citation>page 2</citation>. My problem is that when I copy paste the content like <citation>page 2</citation>, To be or not to be<citation>page 2</citation>. My custom tag gets lost and result is To be or not to bepage 2 instead of To be or not to be<citation>page 2</citation>.

In my config I allow my custom tag:

config = {extraAllowedContent: 'citation'}

My current workaround is the following:

init: function(editor){
        editor.on('contentDom',function()
        {
            editor.on('paste', function(e)
            {
                var focusManager = new CKEDITOR.focusManager(editor);
                if(focusManager.hasFocus)
                {
                    e.data.dataValue = "<span class='paste'>" + e.data.dataValue + "</span>" //wraps it in a utils tag
                }
            });

            editor.on('afterPaste', function(e)
            {
                var focusManager = new CKEDITOR.focusManager(editor); //unwraps it again
                if(focusManager.hasFocus)
                {
                    var $content = $("<div/>").html(editor.getData());
                    $content.find("span.paste").children().unwrap();
                    editor.setData($content.html());
                }
            });
        });
    },

Before pasting it wraps content to be pasted into a span and removes it after pasting again. I know there is a similiar question about my problem. However, I wonder what would be the correct way. Can somebody help me? Thanks.


Solution

  • In order to use custom inline elements, you would need to modify DTD object as shown below:

    //<customtag><span style="background-color:blue;">test</span></customtag>
    CKEDITOR.dtd.customtag = { '#' : 1, 'span' : 1, 'img' : 1 }; // Only text, spans and images are allowed as content of custom tag
    CKEDITOR.dtd.$inline.customtag = 1;// Custom tag is inline
    CKEDITOR.dtd.body.customtag = 1; // Body may contain customtag.
    var editor = CKEDITOR.replace( 'editor1', {
        extraAllowedContent : 'customtag(*)[*]{*}'
    });
    

    If however you would like to use block-level tags then you need to modify CKEditor DTD source code and build your custom editor instance. More on this can be read under this thread: ckeditor how to allow for .insertHtml("<customTag myAttr='value'"></customTag>").

    NOTE: I personally would not recommend going into custom tags too much. Please remember that browsers in general don't know these tags and the more fancy stuff you need to make the deeper you have to go and the better the chance you will get into some browser quirk. With block-level tags their inner content can be moved out of the tag. In case of inline tags you may get unexpected extra text wrapping when using empty custom tags like <variable data-custom-attr="text value" /> (you should use <variable data-custom-attr="text value"></variable> instead).