paste the following contents to the editor
<ul class="list-paddingleft-2" style="list-style-type: circle;"> <li><p><span style="color: rgb(217, 33, 66);font-size: 18px;"><strong>Science 自然科学</strong> </span></p></li><li><p><span style="color: rgb(217, 33, 66);font-size: 18px;"><strong>Social Studies 社会历史地理人文(“社科”)</strong></span></p></li></ul><p style="white-space: normal;"><img src=""></p>
The post editor shows as follows:
<figure class="image ck-widget" contenteditable="false"><img src=""><figcaption class="ck-editor__editable ck-editor__nested-editable ck-hidden ck-placeholder" ''contenteditable="true" data-placeholder="输入图片标题"><br data-cke-filler="true"></figcaption></figure><p><span style="font-size:18px;"><strong>Social Studies 社会历史地理人文(“社科”)</strong></span></p><p><span style="font-size:18px;"><strong>Science 自然科学</strong></span></p>
The order of pictures and words has changed.
Hi, @gongzhiq.
Where do you paste that content from? Is it from MS Docs or Google Docs?
I can confirm the incorrect order, I've been able to reproduce it on the https://ckeditor5.github.io/ with editor.setData() and editor.getData().
cc @f1ames.
Hmm... there are <p>s in <li>s and the editor does not allow that. In that case the conversion needs to clean this up. Apparently, it may be breaking the order.
Funnily, that may explain this bug: https://github.com/ckeditor/ckeditor5/issues/1264. It's very probable that in the content that we get from GDocs there are li > p structures.
@ma2ciek, while I'm also curious where this content comes from, it can actually be copied from anywhere. You can have a similar markup on any website and CKEditor 5 should handle it gracefully.
The original content

Paste it into the editor

The text order in ul changes, and the order of ul and img changes
Paste code:
const clipboardPlugin = editor.plugins.get('Clipboard');
const editingView = editor.editing.view;
editingView.document.on( 'clipboardInput', ( evt, data ) => {
if ( editor.isReadOnly ) {
return false;
}
const dataTransfer = data.dataTransfer;
let content = dataTransfer.getData('textml');
content = clipboardPlugin._htmlDataProcessor.toView(dealCopyFormat(content));
clipboardPlugin.fire('inputTransformation', {content});
editingView.scrollToTheSelection();
evt.stop();
});
Simply using (on e.g. https://ckeditor5.github.io/):
editor.setData('<ul><li><p>1</p></li><li><p>2</p></li></ul>')
reproduces this issue.
I closed https://github.com/ckeditor/ckeditor5/issues/1264 as a DUP of this ticket. Let's not forget to mention in the changelog that a fix for this issue fixes also this case for pasting from GDocs.
There is some issue with view to model conversion here.
With the editor without List plugin, setting HTML like:
<ul>
<li>Foo</li>
</ul>
results in model data like:
<$root>
<paragraph>1</paragraph>
</$root>
and with List plugin:
<$root>
<listItem listIndent="0" listType="bulleted">1</listItem>
</$root>
When list item content is wrapped into another block element:
<ul>
<li>
<p>Foo</p>
</li>
</ul>
without List plugin, model data is:
<$root>
<paragraph></paragraph>
<paragraph>1</paragraph>
<paragraph></paragraph>
</$root>
the result is fine, because empty paragraphs are skipped during downcasting.
And with List plugin:
<$root>
<listItem listIndent="0" listType="bulleted"></listItem>
<paragraph>1</paragraph>
<listItem listIndent="0" listType="bulleted"></listItem>
</$root>
still the same as above, the result is fine as empty list items are skipped during downcasting. I'm not sure ATM if this is an intended behaviour or there should be only two elements (for example two <paragraphs> - one for empty list and another one for <p> as it was extracted from the list). cc @Reinmar
Now, when list (or two subsequent lists) with more than one item with block content is set:
<ul>
<li>
<p>1</p>
</li>
</ul>
<ol>
<li>
<p>2</p>
</li>
</ol>
the model data is (editor with List plugin):
<$root>
<listItem listIndent="0" listType="bulleted"></listItem>
<listItem listIndent="0" listType="numbered"></listItem>
<paragraph>2</paragraph>
<listItem listIndent="0" listType="numbered"></listItem>
<paragraph>1</paragraph>
<listItem listIndent="0" listType="bulleted"></listItem>
</$root>
So apart from 3 elements (2 list items and a paragraph) created during view to model transformation there is an issue with proper insertion position of these elements which seems to be related to List plugin list/converters#viewModelConverter() function. When empty elements are removed during downcasting and paragraphs left, the order is invalid/reversed.
It seems to be even more complex problem when you have multiple block elements inside list item. Since list conversion works in a way that it creates list element and then converts its children, when block element is encountered inside a children list it is extracted after create list item, for example:
<ul>
<li>
Foo
<p>Bar</p>
</li>
</ul>
will be transformed into:
<ul>
<li>Foo</li>
</ul>
<p>Bar</p>
which generally makes sense as text stays inside list item and block element is moved outside keeping the correct order of elements/text. However, with HTML like:
<ul>
<li>
<p>Foo</p>
Bar
</li>
</ul>
the result is:
<ul>
<li>Bar</li>
</ul>
<p>Foo</p>
which means the elements/content order is invalid/reversed.
And for HTML like:
<ul>
<li>
Foo
<p>Bar</p>
Baz
</li>
</ul>
the only reasonable result should be:
<ul>
<li>Foo</li>
</ul>
<p>Bar</p>
<ul>
<li>Baz</li>
</ul>
Unless we will decide to 'flatten' list item contents (but the it will affect all other cases too):
<ul>
<li>FooBarBaz</li>
</ul>
Both requires some significant changes in a way how list conversions works.
<$root> <listItem listIndent="0" listType="bulleted"></listItem> <paragraph>1</paragraph> <listItem listIndent="0" listType="bulleted"></listItem> </$root>still the same as above, the result is fine as empty list items are skipped during downcasting. I'm not sure ATM if this is an intended behaviour or there should be only two elements (for example two
<paragraphs>- one for empty list and another one for<p>as it was extracted from the list).
Regarding the above, after analyzing more how things works it looks like that it is intended behaviour which makes sense for such cases. As <p> is not allowed inside <li> elements (from the editor perspective), <p> is the element which splits its <li> parent. The result of such split is <p> surrounded by two <li> elements which is reflected in a model as shown above.