-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Autoparagraphing strips all text attributes #3294
Comments
I am not convinced. If converter gets input that it should convert attribute A on element E it should do exactly this. Not only text nodes may have attributes after all. I know that attribute A will be probably valid only on certain elements but this sounds like asking for trouble. It looks like too broad and deep solution for this problem.
And now you ask converter to be able to convert incorrect model (or rather deal with the situation of incorrect HTML)? My opinion is that converter should do exactly what it is asked to do and it should get correct model to convert. Everything else should be fixed before. Edit: <strong>
<div>
abc
<p>
foo
<img />
bar
</p>
xyz
</div>
</strong> <div>
<strong>abc</strong>
<p>
<strong>foo</strong>
<strong><img /></strong> <!-- bold will not be applied if not allowed in schema !-->
<strong>bar</strong>
</p>
<strong>xyz</strong>
</div> I think it's reasonable that when taking external DOM, we should strive to generate view structure similar to view structure that would be generated by our model->view conversion. Anyway, this is not related to original issue. We should create separate issue for this, but I am not sure where - whether this is more connected with Edit2: |
Back to the issue - kinda... I have a new idea for autoparagraphing. It seems conceptually wrong that the auto-paragraph is added exactly in place of autoparagraphed text, as its direct parent. It feels like we should first check where the paragraph should be placed. Here is proposed solution:
* This has to be done conditionally, of course. If we were marking elements on step 3, autoparagraph only if element was marked, so we won't, for example, put WDYT? |
It seems that above solution would also solve https://github.com/ckeditor/ckeditor5-paragraph/issues/11. However we would have to somehow recognize which elements can be autoparagraphed (besides text). If we know that this kind of can be autoparagraphed we can treat it like a text node (in steps 1. and 2.) and then also autoparagraph in step 4. and 5. |
Well, it may help if I explain the story behind this. First, I've been only thinking on what to do with a text which parent cannot be converted. So, e.g. someone pastes However, during the course of action, I realised that we can't actually focus on the text anyway because So, I added the second mechanism which focuses on block elements. Currently, I think that it handles most of the job when pasting because, usually, you have the content somehow wrapped within some blocks. Do we need the first algorithm then? Perhaps not really. The situations which the disallowed blocks handler wouldn't catch are:
So, correct me if I'm wrong, but perhaps all this is just unnecessary? |
Spoiler alert, since you commented: I have a feeling that multiple issues connected with handling incorrect data exists because there wasn't any global idea how the process should look like, instead there are just fixes for single problems. I am commenting here and will also comment in other issues but after that we need a talk about all of this :). |
☝️ Don't be sad, you should best know that it's rarely possible to cover all the bases with the first implementation :). |
I can check if this helps in current implementation, because I also have a feeling that the first (current) algorithm might be not needed for now. But current implementation seems wrong anyway, because unrecognized elements are treated as BTW. Now as I think of it, actually, we don't need to use such complicated algorithm. Maybe we can skip step 1, 2 and 3, improving steps 4 and 5? |
I've checked it. As expected,
<div>a<b>b</b>c</div>
<div>a<b>b</b>c</div> which resulted in two
<section>a<b>b</b>c</section>
<section>a<b>b</b>c</section> Which resulted in one |
I don't understand. Below you described exactly what would be an expected result for me. So it does or doesn't work correctly? |
That was for |
You wrote it was for Both ways – how the Still, I feel I don't understand your comment. |
I'm not sure that you know how the algorithm works now. It bases on a list of paragraph-like elements. If element doesn't have its own converter and it is one of the paragraph-like elements, then it's converted to a pargraph. However, if it has block content inside (other paragraph-like elements), then it's skipped (that's to handle nested structures – e.g. nested lists). So, the algorithm picks lowest paragraph-like elements and handle them. I don't understand how you'd like to improve it. |
I wrote:
And I meant that I used
I have a feeling that I do, but OTOH there are multiple places that touches autoparagraphing. What I mean is that when you have: <paragraphLike>
foo
<img />
bar
</paragraphLike> Now the converter will recognise that this is a paragraph-like element and will convert all of it's children in Anyway I don't want to upgrade it just for sake of upgrading. I mentioned that because I wanted to change it more drastically, however I realised that it may not need such a big change. BTW:
How this will be converted? <div>foo<div>bar</div>xyz</div> (I haven't checked it but maybe you know the answer from top of your head :)). |
Why? Right now it makes a lot of sense that any block which is similar to paragraph but which cannot be handled tries to become a paragraph. If this cannot be pasted: <div>a<img>b</div> Let's try pasting this: <p>a<img>b</p> Then we go deeper and e.g. the image feature may handle the situation where |
It's similar to: it( 'pastes ul>li>h2+h3+p as h2+h3+p when heading feature is present', () => {
return VirtualTestEditor.create( {
plugins: [ Paragraph, Clipboard, HeadingEngine ]
} )
.then( newEditor => {
const editor = newEditor;
const doc = editor.document;
const clipboard = editor.plugins.get( 'clipboard/clipboard' );
setModelData( doc, '<paragraph>[]</paragraph>' );
clipboard.fire( 'inputTransformation', {
content: parseView( '<ul><li>x</li><li><h2>foo</h2><h3>bar</h3><p>bom</p></li><li>x</li></ul>' )
} );
expect( getModelData( doc ) ).to.equal(
'<paragraph>x</paragraph>' +
'<heading1>foo</heading1><heading2>bar</heading2><paragraph>bom</paragraph>' +
'<paragraph>x[]</paragraph>'
);
} );
} ); So, the outer paragraph-like elements are ignored if |
No, it's not. I guess you meant the "foo" and "xyz" text nodes. So, I guess first we'll have OK, I can see that it's kinda like this: it( 'pastes ul>li>ul>li+li', () => {
return VirtualTestEditor.create( {
plugins: [ Paragraph, Clipboard ]
} )
.then( newEditor => {
const editor = newEditor;
const doc = editor.document;
const clipboard = editor.plugins.get( 'clipboard/clipboard' );
setModelData( doc, '<paragraph>[]</paragraph>' );
clipboard.fire( 'inputTransformation', {
content: parseView( '<ul><li>a<ul><li>b</li><li>c</li></ul></li></ul>' )
} );
expect( getModelData( doc ) ).to.equal(
'<paragraph>a</paragraph>' +
'<paragraph>b</paragraph>' +
'<paragraph>c[]</paragraph>'
);
} );
} ); The "a" is in a paragraph, but that's because we're pasting there. If we're talking about the conversion itself then we have two tests like this: it( 'should convert ul>li>p,text', () => {
const modelFragment = editor.data.parse( '<ul><li><p>a</p>b</li></ul>' );
expect( stringifyModel( modelFragment ) )
.to.equal( '<paragraph>a</paragraph><paragraph>b</paragraph>' );
} );
// "b" is not autoparagraphed because clipboard holder allows text nodes.
// There's a similar integrational test what's going to happen when pasting in paragraph-integration.js.
it( 'should convert ul>li>p,text (in clipboard holder)', () => {
const modelFragment = editor.data.parse( '<ul><li><p>a</p>b</li></ul>', '$clipboardHolder' );
expect( stringifyModel( modelFragment ) )
.to.equal( '<paragraph>a</paragraph>b' );
} ); So, I'm brilliant :D And I guess this works due to autoping text. So, it may not be that unnecessary. Although, we still need to find a better way to perform that. |
Fix: Content autoparagraphing has been improved. "Inline" view elements (converted to attributes or elements) will be now correctly handled and autoparagraphed. Closes #10. Closes #11.
This test won't pass currently:
The reason is that the converter for the
<b>
element will receive a<paragraph>
created automatically for the text inside it. Then, most likely, it will check that that paragraph can't have bold attribute and abort.Perhaps a reasonable solution would be if the callback created by
buildViewConverter
used something like https://github.com/ckeditor/ckeditor5-core/blob/master/src/command/helpers/getschemavalidranges.js (actually – there's a ticket to move this method to the engine – https://github.com/ckeditor/ckeditor5-core/issues/14 – so it can be exactly this function) and apply the attribute to every item in the ranges. It may be a reasonable solution taken cases like pasting HTML such as:Thanks to that deep "application" all text nodes inside the paragraph would get the bold attribute. I emphasised "text nodes" because the image's attribute should be handled by its own converter.
The text was updated successfully, but these errors were encountered: