CKEditor 中自定义自关闭标签的问题
Problems with a custom self-closing tag in CKEditor
我有一个用于在文本中插入标签 <cut />
的插件。
它工作正常,结果是预期的,但在编辑器中 window <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'
});
}
});
呃,我确定我在某个问题中已经彻底解释了这一点,但我找不到它,所以这里有另一个解释:D.
在 CKEditor 中尝试编辑非 HTML 标签之前,必须了解两个重要事实:
CKEditor 是一个 HTML 编辑器。
当然,自定义标签在 HTML 开始越来越流行。你也可以说 XML 是 HTML 的某种概括(虽然不准确,因为它有其他规则),所以如果 CKEditor 处理 HTML 为什么它不处理其他标签同样好。好吧 - 答案很简单 - 因为 HTML 标签有一个意义 并且 CKEditor 知道它。但它不知道您的自定义标签的含义。标签的含义(列表是什么,它有项目,它们是块元素等)对于实现编辑算法至关重要。
很公平,你可以这么说。但是为什么 CKEditor 的配置(例如 CKEDITOR.dtd
对象)没有泛化,所以每个可能的标签的含义都可以配置?因为每次概括都会增加复杂性,而 HTML 编辑已经足够复杂了。
那么为什么 CKEDITOR.dtd
对象存在呢?因为 CKEditor 的一些组件在某种程度上是可配置的。 DTD 对 CKEditor 的 HTML 解析器(主要用于 数据处理)的影响最大,因此这是最可配置的组件.其他算法,如 enter 键处理、backspace/delete、列表编辑(这是一项非常复杂的任务)仅可稍微配置,并且不能保证它们将与您的自定义标签。
编辑发生在浏览器中,部分由浏览器处理。
这个事实很重要,因为它意味着浏览器的功能也在影响 CKEditor 的限制。浏览器必须能够解析和呈现您的标签(幸运的是,这部分在现代浏览器中运行良好 - IE8 是最后一个有大问题的浏览器)并且必须能够编辑它。这意味着 - 呈现插入符、处理选择、处理 backspace、enter 等。由于浏览器不容易扩展,它们的实现 contentEditable
是高度不一致、不兼容和错误的,从一个版本到另一个版本,CKEditor 覆盖了越来越多的它们的本机行为。还不是全部(实际上 - 它永远不会覆盖所有,因为出于某些原因这可能是灾难性的),但是数量很大。例如,所有 enter 键行为都是自定义的,在 Webkit 和 Blink CKEditor 上处理 backspace 和 delete在许多情况下,由于仍未解决的错误 (1 and 2),它实现了自己的撤消系统,拦截粘贴和删除的内容并执行自定义 HTML 插入(我记得当我们实现它时,这关闭了一个巨大的数字门票)等等,等等
确保一致、可配置和强大的编辑体验的最大努力之一是 widgets system. It is full of hacks inside, but it exposes a clean and pretty powerful API 对开发人员和对最终用户非常一致的行为。它允许实现 "special rich content units that are groups of elements which are treated as a single entity inside the editor"。所以widgets系统有能力封装你的部分内容,并将其与浏览器隔离。
经过这个简短的介绍,我终于可以回答你的问题了。 您需要将 <cut>
标签实现为小部件。您已经很好地配置了 DTD(您只是忘记设置 <cut>
元素可以存在于哪些元素中以及它更像是块元素还是内联元素),因此解析器将接受它并将其作为空标记处理.现在您需要用一个小部件包装它以将其隔离,这样就不会破坏编辑体验。这应该可以解决问题。
我有一个用于在文本中插入标签 <cut />
的插件。
它工作正常,结果是预期的,但在编辑器中 window <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'
});
}
});
呃,我确定我在某个问题中已经彻底解释了这一点,但我找不到它,所以这里有另一个解释:D.
在 CKEditor 中尝试编辑非 HTML 标签之前,必须了解两个重要事实:
CKEditor 是一个 HTML 编辑器。
当然,自定义标签在 HTML 开始越来越流行。你也可以说 XML 是 HTML 的某种概括(虽然不准确,因为它有其他规则),所以如果 CKEditor 处理 HTML 为什么它不处理其他标签同样好。好吧 - 答案很简单 - 因为 HTML 标签有一个意义 并且 CKEditor 知道它。但它不知道您的自定义标签的含义。标签的含义(列表是什么,它有项目,它们是块元素等)对于实现编辑算法至关重要。
很公平,你可以这么说。但是为什么 CKEditor 的配置(例如
CKEDITOR.dtd
对象)没有泛化,所以每个可能的标签的含义都可以配置?因为每次概括都会增加复杂性,而 HTML 编辑已经足够复杂了。那么为什么
CKEDITOR.dtd
对象存在呢?因为 CKEditor 的一些组件在某种程度上是可配置的。 DTD 对 CKEditor 的 HTML 解析器(主要用于 数据处理)的影响最大,因此这是最可配置的组件.其他算法,如 enter 键处理、backspace/delete、列表编辑(这是一项非常复杂的任务)仅可稍微配置,并且不能保证它们将与您的自定义标签。编辑发生在浏览器中,部分由浏览器处理。
这个事实很重要,因为它意味着浏览器的功能也在影响 CKEditor 的限制。浏览器必须能够解析和呈现您的标签(幸运的是,这部分在现代浏览器中运行良好 - IE8 是最后一个有大问题的浏览器)并且必须能够编辑它。这意味着 - 呈现插入符、处理选择、处理 backspace、enter 等。由于浏览器不容易扩展,它们的实现
contentEditable
是高度不一致、不兼容和错误的,从一个版本到另一个版本,CKEditor 覆盖了越来越多的它们的本机行为。还不是全部(实际上 - 它永远不会覆盖所有,因为出于某些原因这可能是灾难性的),但是数量很大。例如,所有 enter 键行为都是自定义的,在 Webkit 和 Blink CKEditor 上处理 backspace 和 delete在许多情况下,由于仍未解决的错误 (1 and 2),它实现了自己的撤消系统,拦截粘贴和删除的内容并执行自定义 HTML 插入(我记得当我们实现它时,这关闭了一个巨大的数字门票)等等,等等确保一致、可配置和强大的编辑体验的最大努力之一是 widgets system. It is full of hacks inside, but it exposes a clean and pretty powerful API 对开发人员和对最终用户非常一致的行为。它允许实现 "special rich content units that are groups of elements which are treated as a single entity inside the editor"。所以widgets系统有能力封装你的部分内容,并将其与浏览器隔离。
经过这个简短的介绍,我终于可以回答你的问题了。 您需要将 <cut>
标签实现为小部件。您已经很好地配置了 DTD(您只是忘记设置 <cut>
元素可以存在于哪些元素中以及它更像是块元素还是内联元素),因此解析器将接受它并将其作为空标记处理.现在您需要用一个小部件包装它以将其隔离,这样就不会破坏编辑体验。这应该可以解决问题。