CKEditor中自定义自关闭标记的问题

时间:2015-04-11 17:44:47

标签: javascript html ckeditor

我有一个插件,用于在文本中插入标记<cut />。 它工作正常,结果可以预期,但在编辑器窗口<cut />转换为<cut></cut>,包含下面的段落并阻碍进一步编辑。

GIF - http://gyazo.com/dd7c36ba7cb7bc7cb00186cfb83e5fbc

任何想法如何解决?

CKEDITOR.plugins.add('pagecut', {
lang: 'de,en,ru',
onLoad: function(){
    var css = ('display:block;clear:both;width:100%;border-top:#999 1px dotted;padding:0;height:1px;cursor:default;');
    var cssBefore = (
            'content:"";' +
            'background: url(' + CKEDITOR.getUrl( this.path + 'images/image.png' ) + ') no-repeat right center;' +
            'height:14px;width:25px;position:relative;display:block;top:-8px;float:right;'
        );
    CKEDITOR.addCss( 'cut{' + css + '} cut:before{' + cssBefore + '}' );
},
init: function(editor) {
    CKEDITOR.dtd['cut'] = {};
    CKEDITOR.dtd.$empty['cut'] = 1;
    CKEDITOR.dtd.$nonEditable['cut'] = 1;
    CKEDITOR.dtd.$object['cut'] = 1;
    editor.addCommand('insertPagecut', {
        exec: function(editor) {
            var element = CKEDITOR.dom.element.createFromHtml('<cut />');
            editor.insertElement(element);
        }
    });

    editor.ui.addButton('Pagecut', {
        label: editor.lang.pagecut.toolbar,
        command: 'insertPagecut',
        icon: this.path + 'images/icon.png',
        toolbar: 'links'
    });
}
});

1 个答案:

答案 0 :(得分:4)

呃,我确信我在某些问题上已经彻底解释了这一点,但是我找不到它,所以这里有另一种解释:D。

在尝试编辑CKEditor中的非HTML标记之前,必须先了解两个重要事实:

  1. CKEditor是 HTML 编辑器。

    当然,自定义标签在HTML中越来越受欢迎。你也可以说XML是某种HTML的泛化(尽管不是很精确,因为它有其他规则),所以如果CKEditor处理HTML,为什么它不能同样处理其他标记。嗯 - 答案很简单 - 因为HTML标签具有含义而CKEditor知道它。但它不知道您的自定义标签的含义。标签的含义(列表是什么,它有项目,它们是块元素等)对于实现编辑算法至关重要。

    很公平,你可以说。但是为什么不对CKEditor的配置(例如CKEDITOR.dtd对象)进行概括,以便可以配置每个可能的标记的含义?因为每次泛化都会增加复杂性,HTML编辑已经足够复杂了。

    那么为什么CKEDITOR.dtd对象存在呢?因为CKEditor的某些组件在某种程度上是可配置的。 DTD对CKEditor HTML parser(主要在data processing期间使用)影响最大,因此这是最可配置的组件。其他算法,如输入键处理,退格/删除,列表编辑(这是一项非常复杂的任务)只是稍微可配置,并且无法保证它们可以与您的自定义标签一起使用。 / p>

  2. 编辑在浏览器中进行,部分由浏览器处理。

    这一事实非常重要,因为这意味着浏览器的功能也会影响CKEditor的限制。浏览器必须能够解析和呈现您的标签(幸运的是,这部分在现代浏览器中运行得相当好 - IE8是最后一个存在巨大问题的部分)并且必须能够编辑它。这意味着 - 渲染插入符号,句柄选择,处理退格输入等。由于浏览器不易扩展且contentEditable的实现高度不一致,不兼容从发布到发布,CKEditor覆盖了越来越多的本机行为。还不是全部(实际上 - 它永远不会覆盖所有,因为由于某些原因可能是灾难性的),但是数量很大。例如,所有 enter 键行为都是自定义的,在Webkit和Blink CKEditor处理 backspace delete 在许多情况下由于仍然没有解决的bug( 12),它实现了自己的撤消系统,拦截粘贴和删除的内容并执行自定义HTML插入(我记得当我们实现它时关闭了大量的票证)等,等

    确保一致,可配置和强大的编辑体验的最大努力之一是widgets system。它内部充满了黑客攻击,但它为开发人员提供了一个干净且非常强大的API,并为最终用户提供了非常一致的行为。它允许实现“特殊的富内容单元,这些单元是在编辑器中被视为单个实体的元素组”。因此,小部件系统可以封装部分内容并将其与浏览器隔离。

  3. 在这个简短的介绍后,我终于可以回答你的问题。 您需要将<cut>标记实现为小部件。您已经很好地配置了DTD(您只是忘了设置<cut>元素可以存在的元素以及它是否更像是块或内联元素),因此解析器将接受它并作为空标记处理。现在你需要用一个小部件包装它以隔离它,这样它就不会破坏编辑体验。这应该可以解决问题。