Inserting blank P tags before and after fake element
Andrew Henderson
I'm new to CKEditor, writing my first plugin and i just can't find the answer to this one anywhere.
I have a plugin which creates a div element in the source containing just the text !!!!!NEWSTABLE!!!!!. The class attribute is set to newsDiv. On the WYSIWYG editor, I just want it to display a fake placeholder element. This works fine, the problem is that when I switch back to WYSIWYG mode after having been in source mode, it inserts blank paragraph tags above and below the inserted div.
Switching enterMode to CKEDITOR.ENTER_BR fixes this, but I would still like the enter key to make a paragraph rather than a break-space.
My plugin code (inspired by the flash plugin source code) is as follows:
(function() { function isNewsEmbed(element) { return (element.attributes.class == 'newsDiv'); } function createFakeElement(editor, realElement) { return editor.createFakeParserElement(realElement, 'cke_news', 'div', false); } CKEDITOR.plugins.add('newsTable', { init: function(editor) { var pluginName = 'newsTable'; editor.ui.addButton('NewsTable', { label: 'Add News Section', icon: ' command: pluginName }); editor.addCommand(pluginName, { exec: function(editor) { var node = new CKEDITOR.dom.element('div'); node.setAttribute('class', 'newsDiv'); node.setHtml('!!!!!NEWSTABLE!!!!!'); elem = editor.createFakeElement(node, 'cke_news', 'div', false) editor.insertElement(elem); } }); var css = 'img.cke_news{' + 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/placeholder.png' ) + ');' + 'background-position: center center;' + 'background-repeat: no-repeat;' + 'border: 1px solid #a9a9a9;' + 'width: 80px;' + 'height: 80px;' + '}'; editor.addCss(css); }, afterInit: function(editor) { var dataProcessor = editor.dataProcessor, dataFilter = dataProcessor && dataProcessor.dataFilter; if (dataFilter) { dataFilter.addRules({ elements: { 'div' : function( element ) { var attributes = element.attributes, classId = attributes.classid && String( attributes.classid ).toLowerCase(); if (!classId && isNewsEmbed(element)){ return createFakeElement( editor, element ); } return null; } } }); } }, requires : [ 'fakeobjects' ] });
})();After pressing the button that activates this plugin, I press 'Source' and it is as expected...
<p>
<div> !!!!!NEWSTABLE!!!!!</div>
</p>However, if from there ones goes into WYSIWYG mode and back again (without doing anything else) the code has changed to the following, which i dont expect.
<p>
</p>
<div>
!!!!!NEWSTABLE!!!!!</div>
<p>
</p>What am I doing wrong?
1 Answer
I know it's a rather late answer (I was searching to solve another issue, and stumbled upon this question), but the reason you can't do this, is because both the <p> and <div> tags are "block level" elements, and you can't put a block level element in another block level element. (It's just invalid HTML).
CKEditor automatically repairs this, in the way you're seeing above.
2