为什么 CKEditor 拒绝我的自定义标签?

Why is CKEditor refusing my custom tag?

使用自定义 CKEditor 插件,我试图插入一个自定义 HTML 标签,但该标签在插入编辑器后立即被删除。我的 plugin.js 文件:

CKEDITOR.plugins.add( 'tweet', {
    icons: 'tweet',
    init: function( editor ) {
        editor.addCommand( 'insertTweet', {
            allowedContent: 'tweet[:id]',
            requiredContent: 'tweet',
            exec: function( editor ) {
                console.log('inserting');  
                editor.insertHtml( '<tweet :id="\'123\'" />' );  // also tried <tweet />
                // editor.insertHtml( '[tweet :id="\'123\'" /]' ); // this works
            }
        });

        editor.ui.addButton( 'tweet', {
            label: 'Insert tweet',
            command: 'insertTweet',
            toolbar: 'insert,0'
        });
    }
});

我为 Bolt CMS 后端添加插件的方式:

function run() {
    var extrasAdded = false;

    if (typeof(CKEDITOR) == 'undefined') return;

    CKEDITOR.plugins.addExternal('tweet', '/assets/plugins/tweet/plugin.js', '');

    CKEDITOR.on('instanceReady', function (event, instance) {

        if (extrasAdded === true) return;

        var config = event.editor.config;

        config.toolbar.push(
            { name: 'insert', items: [ 'tweet' ] }
        );
        config.extraPlugins += (config.extraPlugins ? ',' : '') + 'tweet';
        config.extraAllowedContent = 'tweet';  // also tried 'tweet[:id]'

        CKEDITOR.instances['body'].destroy();
        CKEDITOR.replace('body', config);

        extrasAdded = true;
    });
}

if (document.readyState!='loading') run();
else document.addEventListener('DOMContentLoaded', run);

聪明的人能看出我的标签被拒绝的原因吗?

所以事实证明我们不需要 plugin.js 脚本中的 allowedContentrequiredContent 属性。诀窍是调整编辑器的 HTML DTD rules。在我的例子中,我在 instanceReady 回调中得到了对编辑器的引用,并像这样调整它:

// name = 'tweet'
editor.filter.allow(name + "[!*]", name, true);

CKEDITOR.dtd[name] = CKEDITOR.dtd;
CKEDITOR.dtd.$empty[name] = 1; // allow self-closing tag
CKEDITOR.dtd.$blockLimit[name] = 1;
CKEDITOR.dtd.$nonEditable[name] = 1;
CKEDITOR.dtd.$object[name] = 1;
CKEDITOR.dtd.$inline[name] = 1; // $block won't work!

您还可以看到完整的gist of it