Search code examples
javascriptjquerydrupal-7ckeditor

How to freeze html created by CKEditor plugin


I having an issue with creating custom span tag using custom CKEditor plugin. The plugin takes user input for dataAttribute, dataValue and specificContent. Then on onOk for the dialog, I create a span element and append it to the editor.

// Create the span element
var span = new CKEDITOR.dom.element('span');
// Add the attributes to the span.
span.data(dataAttribute, dataValue);
span.setHtml(specificContent);
// span.contentEditable = false;
// Finally insert the element into the editor.
editor.insertElement(span);

// I have created a dummy element to place the cursor outside the actual span tag.
var dummySpan = new CKEDITOR.dom.element('span');
dummySpan.addClass('dummy-span');
dummySpan.setText(' ');

// after section dealing with editing a selected item, in "else":
var sel = editor.getSelection(); // current cursor position
editor.insertElement(span); // the real new element
if(CKEDITOR.env.ie || CKEDITOR.env.webkit) {
    dummySpan.insertAfter(span);
    sel.selectElement(dummySpan);
}
else {
    dummySpan.insertAfter(span);
    var rangeObjForSelection = new CKEDITOR.dom.range( editor.document );
    rangeObjForSelection.selectNodeContents(dummySpan);
    editor.getSelection().selectRanges( [ rangeObjForSelection ] );
}

The code works well and the expected markup is generated and inserted at the cursor position. For eg:

<span data-school='seven-high'>Seven High, Eleven</span>
<span class='dummy'></span>

The problem is that on continuous usage of the plugin widget. The markup can turn as faulty. This is because the cursor can be placed inside the span tag. For eg.: After inserting the first span content, the cursor is at span.dummy, if I add a space and then try to add second span content, the space is added inside the span.dummy and the wrong markup is generated for second span content.

<span data-school='seven-high'>Seven High, Eleven</span>
<span class='dummy'>&nbsp;
  <span data-school='seven-high'>Seven High, Eleven</span>
  <span class='dummy'></span>
  <span data-school='seven-high'>Seven High, Eleven</span>
  <span class='dummy'></span>
</span>

or

<span data-school='seven-high'>Seven High, Eleven</span>
<span class='dummy'>&nbsp;
  <span data-school='seven-high'>Seven High, Eleven</span>
  <span class='dummy'>
    <span data-school='seven-high'>Seven High, Eleven</span>
    <span class='dummy'></span>
  </span>
</span>

Expected markup for above:

<span data-school='seven-high'>Seven High, Eleven</span>
<span class='dummy'></span>
<span data-school='seven-high'>Seven High, Eleven</span>
<span class='dummy'></span>
<span data-school='seven-high'>Seven High, Eleven</span>
<span class='dummy'></span>

Is there a way to secure that the user will never be able to place the cursor inside the CKEditor created span tag i.e. freeze the span tag created by CKEditor?

Note: I am also using data processors: dataFilter and htmlFilter.

This is my first attempt to create a CKEditor plugin (for Drupal WYSIWYG). So I am open to all the solution to this problem. Note: the span tags should be created as expected using the solution.


Solution

  • IMO it would be better to disallow inserting new span.dummy inside already existing one, not to "freeze" some content inside the editor.

    You can detect with elements path in which element the selection currently is. If it's inside span.dummy, just insert new one before/after the existing one – example.

    If you really want to freeze content, then you can try to add [contenteditable=false] attribute to such elements or to turn them into widgets (Placeholder plugin could be a good place to start)