0
votes

I have an inline web page editor which allows the user to edit the content (specified in the div id='saveableContent') for each page.

I'm using CKEditor 4.2.1 along with the Youtube plugin: https://github.com/fonini/ckeditor-youtube-plugin

The inline editor has multiple contenteditable='true' divs for the parts of the page that can be editable, much like following: the http://nightly.ckeditor.com/14-01-03-07-05/standard/samples/inlineall.html

I will post an example with only one contenteditable div but note that there may be multiple on a page. Before I was using the YouTube plugin, I would simply save the entire content by getting:

$('#saveableContent').html();

which kept all the code intact. However, once I started using the YouTube plugin, when adding a YouTube video it displays it as an iFrame image.

<div aria-describedby="cke_66" title="Rich Text Editor, content" aria-label="Rich Text Editor, content" role="textbox" style="position: relative;" spellcheck="false" tabindex="0" class="entry editablecontent cke_editable cke_editable_inline cke_contents_ltr cke_show_borders cke_focus" id="content" contenteditable="true">
<!--{cke_protected}{C}%3C!%2D%2D%20Home%20page%20heading%20%2D%2D%3E--><h2>Freight</h2>
<!--{cke_protected}{C}%3C!%2D%2D%20Para%20%2D%2D%3E-->
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br></p><p><span></span>
   <img class="cke_iframe" data-cke-realelement="%3Ciframe%20src%3D%22%2F%2Fwww.youtube.com%2Fembed%2F3i_bsfwPE1s%22%20allowfullscreen%3D%22%22%20frameborder%3D%220%22%20height%3D%22360%22%20width%3D%22640%22%3E%3C%2Fiframe%3E" data-cke-real-node-type="1" alt="IFrame" title="IFrame" src="http://pcbca-new.dev/ckeditor/plugins/fakeobjects/images/spacer.gif?t=D7UD" data-cke-real-element-type="iframe" data-cke-resizable="true" style="width:640px;height:360px;" align="">
   <br></p><br></div>

In order for it to convert to a real iFrame html, I would need to use

CKEDITOR.instances.content.getData(); 

Which contains the real converted iFrame code:

<!-- Home page heading -->
<h2>Freight</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p><iframe allowfullscreen="" frameborder="0" height="360" src="//www.youtube.com/embed/3i_bsfwPE1s" width="640"></iframe><span>&nbsp;</span><span>&nbsp;</span></p>

but the problem is, it strips out all my divs that contain the contenteditable='true' so the next round the page is loaded for editing, none of the sections are editable anymore.

Sooooo.... I want to be able to maintain all the code as is ($('#saveableContent').html();) but at the same time have the iFrame image converted to a real iFrame (CKEDITOR.instances.content.getData();).

I thought maybe I can disable the automatic cleaning of the code by CKEditor so I tried

config.allowedContent = true;

But that didn't work.

What can I do to ensure that all iFrame images on the page are converted to the real iFrame code while at the same time the div's are maintained with all it's attributes?

1

1 Answers

0
votes

While CKEditor protects iframes, scripts videos and stuff while running, I see several solutions of your problem, depending on your needs:

  1. The "right way": Don't save the contents of #saveableContent as a whole but iterate over CKEDITOR.instances and collect editor.getData(). Then, when rendering the page de-serialize that HTML (quite likely an array of editor contents) back into editors in #saveableContent (editor.setData( html )). This way #saveableContent is never stored in database and you gain control over your HTML: you can discard/modify/alter contents of a particular editor if you need.

  2. The "somewhat right way": Iterate over CKEDITOR.instances and collect editor.getData(). Concatenate it with a string '<div id="saveableContent">' + ... + '</div>'. Note that your data is not structured any longer.

  3. The "nasty way": Iterate over CKEDITOR.instances and call editor.destroy() before saving the contents of #saveableContent. Note that it may be no solution for you if you want to keep editors alive (i.e. "auto-save").