CKEditor:多个小部件模板
CKEditor: multiple widget templates
我目前正在创建一个 'smartobject' 小部件。在小部件对话框中,用户可以选择 'smartobject',简单地说,生成一些 html,应该将其添加到编辑器中。棘手的部分来了:html 有时是 div 元素,有时只是跨越元素。在 div 变体的情况下,小部件应包装在 div 'template' 中。在 span 变体的情况下,小部件应包含在 span 中,并且应添加 html 'inline'。
在小部件中 API 我看到了以下定义模板的方法:
editor.widgets.add('smartobject', {
dialog: 'smartobject',
pathName: lang.pathName,
template: '<div class="cke_smartobject"></div>', // <------
upcast: function(element) {
return element.hasClass('smartObject');
},
init: function() {
this.setData('editorHtml', this.element.getOuterHtml());
},
data: function() {
var editorHtml = this.data.editorHtml;
var newElement = new CKEDITOR.dom.element.createFromHtml(editorHtml);
newElement.copyAttributes(this.element);
this.element.setText(newElement.getText());
}
});
但在我的例子中,模板更加动态:有时 div 有时 span 会做正确的事情..
如何解决这个问题而不需要创建两个完全相同的小部件,只是包装元素有所不同?
我已经尝试在 'data' 方法中替换整个元素,例如:
newElement.replace(this.element);
this.element = newElement;
但这似乎不受支持:调用 editor.getData() 后导致未定义的错误。
我正在使用 ckeditor v4.5.9
感谢您的帮助!
正如 this ckeditor 论坛帖子中所建议的那样,最好的方法是将模板设置为包含所有可能的内容元素。然后,在data
函数中,根据你的具体逻辑去掉不需要的部分。
看来我成功了(有解决方法)。
代码:
CKEDITOR.dialog.add('smartobject', this.path + 'dialogs/smartobject.js');
editor.widgets.add('smartobject', {
pathName: lang.pathName,
// This template is needed, to activate the widget logic, but does nothing.
// The entire widgets html is defined and created in the dialog.
template: '<div class="cke_smartobject"></div>',
init: function() {
var widget = this;
widget.on('doubleclick', function(evt) {
editor.execCommand('smartobject');
}, null, null, 5);
},
upcast: function(element) {
return element.hasClass('smartObject');
}
});
// Add a custom command, instead of using the default widget command,
// otherwise multiple smartobject variants (div / span / img) are not supported.
editor.addCommand('smartobject', new CKEDITOR.dialogCommand('smartobject'));
editor.ui.addButton && editor.ui.addButton('CreateSmartobject', {
label: lang.toolbar,
command: 'smartobject',
toolbar: 'insert,5',
icon: 'smartobject'
});
在对话框中,插入代码如下所示:
return {
title: lang.title,
minWidth: 300,
minHeight: 80,
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
editor.insertElement(element);
// Trigge the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
},
...etc.
更新
我改进了 'onOk' 方法:插入后现在选择了 smartobject 元素。
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
var elementId = "ckeditor-element-" + element.getUniqueId();
element.setAttribute("id", elementId);
editor.insertElement(element);
// Trigger the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
// Get the element 'fresh' by it's ID, because the setData method,
// makes the element change into a widget, and thats the element which should be selected,
// after adding.
var refreshedElement = CKEDITOR.document.getById(elementId);
var widgetWrapperElement = CKEDITOR.document.getById(elementId).getParent();
// Better safe then sorry: if the fresh element doesn't have a parent, simply select the element itself.
var elementToSelect = widgetWrapperElement != null ? widgetWrapperElement : refreshedElement;
// Normally the 'insertElement' makes sure the inserted element is selected,
// but because we call the setData method (to ensure the element is transformed to a widget)
// the selection is cleared and the cursor points to the start of the editor.
editor.getSelection().selectElement(elementToSelect);
},
所以简而言之,我部分地使用了小部件 API 作为我想要的部分:
- 使小部件的 html 不可编辑
- 使其可移动
但我创建了一个自定义对话框命令,它简单地绕过了默认的小部件插入,因此我可以完全决定我自己的 html 小部件结构。
一切似乎都是这样。
如有任何改进建议,我们将不胜感激:)!
我目前正在创建一个 'smartobject' 小部件。在小部件对话框中,用户可以选择 'smartobject',简单地说,生成一些 html,应该将其添加到编辑器中。棘手的部分来了:html 有时是 div 元素,有时只是跨越元素。在 div 变体的情况下,小部件应包装在 div 'template' 中。在 span 变体的情况下,小部件应包含在 span 中,并且应添加 html 'inline'。
在小部件中 API 我看到了以下定义模板的方法:
editor.widgets.add('smartobject', {
dialog: 'smartobject',
pathName: lang.pathName,
template: '<div class="cke_smartobject"></div>', // <------
upcast: function(element) {
return element.hasClass('smartObject');
},
init: function() {
this.setData('editorHtml', this.element.getOuterHtml());
},
data: function() {
var editorHtml = this.data.editorHtml;
var newElement = new CKEDITOR.dom.element.createFromHtml(editorHtml);
newElement.copyAttributes(this.element);
this.element.setText(newElement.getText());
}
});
但在我的例子中,模板更加动态:有时 div 有时 span 会做正确的事情..
如何解决这个问题而不需要创建两个完全相同的小部件,只是包装元素有所不同?
我已经尝试在 'data' 方法中替换整个元素,例如:
newElement.replace(this.element);
this.element = newElement;
但这似乎不受支持:调用 editor.getData() 后导致未定义的错误。
我正在使用 ckeditor v4.5.9
感谢您的帮助!
正如 this ckeditor 论坛帖子中所建议的那样,最好的方法是将模板设置为包含所有可能的内容元素。然后,在data
函数中,根据你的具体逻辑去掉不需要的部分。
看来我成功了(有解决方法)。 代码:
CKEDITOR.dialog.add('smartobject', this.path + 'dialogs/smartobject.js');
editor.widgets.add('smartobject', {
pathName: lang.pathName,
// This template is needed, to activate the widget logic, but does nothing.
// The entire widgets html is defined and created in the dialog.
template: '<div class="cke_smartobject"></div>',
init: function() {
var widget = this;
widget.on('doubleclick', function(evt) {
editor.execCommand('smartobject');
}, null, null, 5);
},
upcast: function(element) {
return element.hasClass('smartObject');
}
});
// Add a custom command, instead of using the default widget command,
// otherwise multiple smartobject variants (div / span / img) are not supported.
editor.addCommand('smartobject', new CKEDITOR.dialogCommand('smartobject'));
editor.ui.addButton && editor.ui.addButton('CreateSmartobject', {
label: lang.toolbar,
command: 'smartobject',
toolbar: 'insert,5',
icon: 'smartobject'
});
在对话框中,插入代码如下所示:
return {
title: lang.title,
minWidth: 300,
minHeight: 80,
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
editor.insertElement(element);
// Trigge the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
},
...etc.
更新 我改进了 'onOk' 方法:插入后现在选择了 smartobject 元素。
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
var elementId = "ckeditor-element-" + element.getUniqueId();
element.setAttribute("id", elementId);
editor.insertElement(element);
// Trigger the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
// Get the element 'fresh' by it's ID, because the setData method,
// makes the element change into a widget, and thats the element which should be selected,
// after adding.
var refreshedElement = CKEDITOR.document.getById(elementId);
var widgetWrapperElement = CKEDITOR.document.getById(elementId).getParent();
// Better safe then sorry: if the fresh element doesn't have a parent, simply select the element itself.
var elementToSelect = widgetWrapperElement != null ? widgetWrapperElement : refreshedElement;
// Normally the 'insertElement' makes sure the inserted element is selected,
// but because we call the setData method (to ensure the element is transformed to a widget)
// the selection is cleared and the cursor points to the start of the editor.
editor.getSelection().selectElement(elementToSelect);
},
所以简而言之,我部分地使用了小部件 API 作为我想要的部分: - 使小部件的 html 不可编辑 - 使其可移动
但我创建了一个自定义对话框命令,它简单地绕过了默认的小部件插入,因此我可以完全决定我自己的 html 小部件结构。
一切似乎都是这样。
如有任何改进建议,我们将不胜感激:)!