简体   繁体   English

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

[英]Problems with a custom self-closing tag in CKEditor

I have a plugin for inserting tag <cut /> in text. 我有一个插件用于在文本中插入标签<cut /> It works fine, result is expectable, but in editor window <cut /> transforms into <cut></cut> , wraps the paragraphs below and hampers further edits. 它工作正常,结果可以预期,但在编辑器窗口<cut />转换为<cut></cut> ,包含下面的段落并阻碍进一步编辑。

GIF - http://gyazo.com/dd7c36ba7cb7bc7cb00186cfb83e5fbc GIF - http://gyazo.com/dd7c36ba7cb7bc7cb00186cfb83e5fbc

Any ideas how to fix it? 任何想法如何解决它?

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'
    });
}
});

Uh, I'm sure that I explained this thoroughly in some question, but I can't find it, so here goes another explanation :D. 呃,我确信我在某些问题上已经彻底解释了这一点,但我找不到它,所以这里有另一种解释:D。

There are two important facts that one must understand before trying to edit non-HTML tags in CKEditor: 在尝试编辑CKEditor中的非HTML标记之前,必须先了解两个重要事实:

  1. CKEditor is an HTML editor. CKEditor是一个HTML编辑器。

    Of course custom tags start to be more and more popular in HTML. 当然,自定义标签在HTML中越来越受欢迎。 You can also say that XML is some kind of generalisation of HTML (although not precisely, because it has other rules), so if CKEditor handles HTML why doesn't it handle other tags equally well. 你也可以说XML是某种HTML的泛化(尽管不是很精确,因为它有其他规则),所以如果CKEditor处理HTML,为什么它不能同样处理其他标记。 Well - the answer is simple - because HTML tags have a meaning and CKEditor knows it. 嗯 - 答案很简单 - 因为HTML标签有意义而CKEditor知道它。 But it does not know meaning of your custom tags. 但它不知道您的自定义标签的含义。 And the meaning of tags (what a list is, that it has items, that they are block elements, etc.) is crucial to implement editing algorithms. 标签的含义(列表是什么,它有项目,它们是块元素等)对于实现编辑算法至关重要。

    Fair enough, you could say. 很公平,你可以说。 But why wasn't CKEditor's configuration (eg the CKEDITOR.dtd object) generalised so meaning of every possible tag can be configured? 但是为什么CKEditor的配置(例如CKEDITOR.dtd对象)没有概括,所以可以配置每个可能的标签的含义? Because every generalisation increases complexity and HTML editing is already complex enough. 因为每次泛化都会增加复杂性,HTML编辑已经足够复杂了。

    So why does the CKEDITOR.dtd object exist at all? 那么为什么CKEDITOR.dtd对象一直存在呢? Because some components of CKEditor are configurable to some extent. 因为CKEditor的某些组件在某种程度上是可配置的。 The DTD has the biggest impact on CKEditor's HTML parser (which is used mostly during data processing ) so this is the most configurable component. DTD对CKEditor的HTML解析器 (主要在数据处理期间使用)影响最大,因此这是最可配置的组件。 Other algorithms, like the enter key handling, backspace/delete, lists editing (which is a very complex task) are only slightly configurable and there is no guarantee given that they will work with your custom tags. 其他算法,如输入键处理,退格/删除,列表编辑(这是一项非常复杂的任务)只是稍微可配置,并且无法保证它们将与您的自定义标签一起使用。

  2. The editing happens in the browsers and is partially handled by the browsers. 编辑在浏览器中进行 ,部分由浏览器处理。

    This fact is important because it means that browsers' capabilities are affecting CKEditor's limits too. 这个事实非常重要,因为这意味着浏览器的功能也会影响CKEditor的限制。 Browser must be able to parse and render your tags (fortunately, this part works rather well in modern browsers - IE8 is the last one with a huge problems) and must be able to edit it. 浏览器必须能够解析和呈现您的标签(幸运的是,这部分在现代浏览器中运行得相当好 - IE8是最后一个存在巨大问题的部分)并且必须能够编辑它。 This means - render caret, handle selection, handle backspace , enter , etc. Since browsers are not easily extensible and their implementations of contentEditable are highly inconsistent, incompatible and buggy, from release to release CKEditor overrides more and more of their native behaviours. 这意味着 - 渲染插入符号,句柄选择,处理退格键输入等等。由于浏览器不易扩展且contentEditable的实现高度不一致,不兼容和错误,从发布到发布CKEditor会覆盖越来越多的本机行为。 Not all yet (actually - it will never override all, because that could be disastrous for certain reasons), but a significant amount. 还不是全部(实际上 - 它永远不会覆盖所有,因为由于某些原因可能是灾难性的),但是数量很大。 For instance, all the enter key behaviour is custom, on Webkit and Blink CKEditor handles backspace and delete in many scenarios due to still unresolved bugs ( 1 and 2 ), it implements its own undo system, intercepts pasted and dropped content and perform custom HTML insertion (I remember that when we implemented it this closed a huge number of tickets), etc., etc. 例如,所有的回车键行为都是自定义的,在Webkit和Blink CKEditor处理退格删除在许多情况下由于仍然未解决的错误( 12 ),它实现了自己的撤销系统,拦截粘贴和删除的内容并执行自定义HTML插入(我记得当我们实施它时关闭了大量的门票)等等。

    One of the greatest efforts to ensure consistent, configurable and powerful editing experience is the widgets system . 小部件系统是确保一致,可配置和强大的编辑体验的最大努力之一。 It is full of hacks inside, but it exposes a clean and pretty powerful API to the developer and a very consistent behaviour to the end user. 它内部充满了黑客攻击,但它为开发人员提供了一个干净且功能强大的API ,并为最终用户提供了非常一致的行为。 It allows to implement a "special rich content units that are groups of elements which are treated as a single entity inside the editor". 它允许实现“特殊的富内容单元,这些单元是在编辑器中被视为单个实体的元素组”。 So the widgets system has the power to encapsulate part of your content and isolate it from the browsers. 因此,窗口小部件系统可以封装部分内容并将其与浏览器隔离。

After this short introduction I can finally answer your question. 在这个简短的介绍后,我终于可以回答你的问题。 You need to implement your <cut> tag as a widget . 您需要将<cut>标记实现为窗口小部件 You already configured your DTD pretty well (you only forgot to set in what elements the <cut> element can exist and whether it is more like a block or inline element), so the parser will accept it and handle as an empty tag. 您已经很好地配置了DTD(您只是忘记设置<cut>元素可以存在的元素以及它是否更像是块或内联元素),因此解析器将接受它并作为空标记处理。 Now you need to wrap it with a widget in order to isolate it so it does not break the editing experience. 现在你需要用一个小部件包装它以隔离它,这样它就不会破坏编辑体验。 That should do the trick. 这应该够了吧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM