Search code examples
ckeditorckeditor4.x

CKEditor automatically nesting double ul


I wrote a plugin for CKEditor 4 that uses widget and dialog. My widget, simplifying a little bit, consists of a div with a nested ul and a number of li's. For some reason, when I switch from WYSIWYG mode to SOURCE mode, the ul is turned into a double nested ul.

I have defined which elements in the widget should be editables and I have defined which elements should be allowedContent for those editables.

My original structure in WYSIWYG mode (after the dialog closes and the widget is created) is like this:

<div class="mycustombox">
  <div class="conditions-box">
    <div class="conditions-services">
      <span class="rwd-line-title">TITLE FOR THE UNORDERED LIST</span>
      <ul class="services-list">
        <li>an example list item</li>
        <li>another example list item</li>
      </ul>
    </div>
  </div>
</div>

I have double checked that this is the actual html by inspecting the source of the page in the Chrome Developer Console. But when I switch to SOURCE mode, the structure then becomes:

<div class="mycustombox">
  <div class="conditions-box">
    <div class="conditions-services">
      <span class="rwd-line-title">TITLE FOR THE UNORDERED LIST</span>
      <ul class="services-list">
        <ul>
          <li>an example list item</li>
          <li>another example list item</li>
        </ul>
      </ul>
    </div>
  </div>
</div>

The original ul with the class I gave it is there, but there is an extra nested ul wrapping the li elements.

I have defined my allowed widget content in the plugin.js:

allowedContent: 'div(!mycustombox); div(!conditions-box); div(!conditions-services); span(!rwd-line); span(!rwd-line-title); ul(!services-list); li; p; div',
requiredContent: 'div(mycustombox)',
upcast: function( element ) {
    return element.name == 'div' && element.hasClass( 'mycustombox' );
},

And I have defined the ul element as an editable like so:

editables: {
  priceincludes: {
    selector: 'div.conditions-box div.conditions-services ul',
    allowedContent: 'li em strong'
  },
}

I have also allowed ul's to be editable by the general CKEditor instance as so:

CKEDITOR.dtd.$editable[ 'ul' ] = 1;

Is there some setting in the CKEditor configuration which could be causing this behaviour?


Solution

  • Well I don't know if this is the best solution, but it works. Tell CKEDitor to stop trying to automatically wrap li elements with a ul tag. For some reason it's treating them as though they weren't already wrapped in a ul tag. Using this at the beginning of my plugin.js fixes the problem:

        delete CKEDITOR.dtd.$listItem['li'];
        delete CKEDITOR.dtd.$intermediate['li'];    
    

    I got the idea from here: http://margotskapacs.com/2014/11/ckeditor-stop-altering-elements/

    Seems kind of hackish to me, but until I find a better solution I'll just use this.