Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

model#deleteContent() will proper merge elements inside limit element #1559

Merged
merged 10 commits into from
Oct 26, 2018

Conversation

pomek
Copy link
Member

@pomek pomek commented Sep 27, 2018

Suggested merge commit message (convention)

Fix: model#deleteContent() will proper merge elements inside limit element. Closes ckeditor/ckeditor5#1265.

@coveralls
Copy link

coveralls commented Sep 27, 2018

Coverage Status

Coverage remained the same at 100.0% when pulling feb015e on t/ckeditor5/1265 into 08b2a34 on master.

@@ -139,6 +139,11 @@ function mergeBranches( writer, startPos, endPos ) {
startPos = Position.createAfter( startParent );
endPos = Position.createBefore( endParent );

// One more check if both positions ended up in the same parent. See: https://github.com/ckeditor/ckeditor5/issues/1265.
if ( endParent == startPos.parent ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code should land in checkCanBeMerged(). I'm also not sure if this is the right check. See the comment above checkCanBeMerged():

// Check if parents of two positions can be merged by checking if there are no limit/object
// boundaries between those two positions.
//
// E.g. in <bQ><p>x[]</p></bQ><widget><caption>{}</caption></widget>
// we'll check <p>, <bQ>, <widget> and <caption>.
// Usually, widget and caption are marked as objects/limits in the schema, so in this case merging will be blocked.

This is a more general implementation – it's based on checking whether there's no limit elements involved. We know that the case we're currently solving requires that everything happens inside a limit element. I can also see that the condition you wrote is true when endParent is a tableCell (which is a limit element). That makes me suspicious whether the check should be about endParent being equal to startPos.parent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed my solution. Now the merge is blocking if an only single element is between positions (leftPos and rightPos). From my point of view, such merge does not have any sense because there is nothing to merge.

@Reinmar
Copy link
Member

Reinmar commented Oct 4, 2018

I changed my solution. Now the merge is blocking if an only single element is between positions (leftPos and rightPos). From my point of view, such merge does not have any sense because there is nothing to merge.

First of all, I don't understand what's wrong with this scenario. We talk about merging, so if the positions look like this:

<paragraph>foo[</paragraph>
<paragraph>]bar</paragraph>

(nothing between these two positions) then there's still something to merge there – those two paragraphs together. Or do the positions look differently in this case? I can't find how they look in any of your comments.

Secondly, we also need to understand why does the previous code lead this case to such a situation. Perhaps some code that's executed earlier works incorrectly. You say that merge cannot happen in this case. But how we even got to this place?

Those are the questions you need to answer. Step by step you need to investigate this algorithm and we need to see if at any of those steps something wrong happens. I recommend that you list here what are the positions/ranges and model structure at various important points before so we can check this together.

@pomek
Copy link
Member Author

pomek commented Oct 4, 2018

(nothing between these two positions)

I see two elements to merge. Closing a paragraph and opening a paragraph.

@Reinmar
Copy link
Member

Reinmar commented Oct 4, 2018

I see two elements to merge. Closing a paragraph and opening a paragraph.

So it seems that I still don't know how those positions look in the scenario you debug. Please provide more information on what's happening there so we could analyse it together.

@pomek
Copy link
Member Author

pomek commented Oct 4, 2018

I will go with the test case that allows reproducing the issue.

  1. The error occurs in mergeBranches() function so I put a debugger in a line before the function call:

mergeBranches( writer, startPos, endPos );

  1. What we have in the model? getData( model )
<blockLimit>
  <blockQuote>
    <paragraph>Foo[</paragraph>
  </blockQuote>
  <paragraph>]Bar</paragraph>
</blockLimit>
  1. First call of mergeBranches() function does not throw any error. Before recursively calling, let's print some details:
<!-- getDat( model ) -->

<blockLimit>
  <blockQuote>
    <paragraph>Foo[]Bar</paragraph>
  </blockQuote>
</blockLimit>

In fact, we have already the correct result. We shouldn't call mergeBranches() again. But we will do it with params listed below:

startPos.path = [0, 0, 1]
endPos.path = [0, 1]

It means that the function wants to merge </blockQuote> with </paragraph> which produces an error (mentioned in the issue).

@Reinmar
Copy link
Member

Reinmar commented Oct 4, 2018

I think that the bug is here:

if ( !startParent.parent || !endParent.parent ) {
return;
}

See the comment:

	// If one of the positions is a root, then there's nothing more to merge (at least in the current state of implementation).
	// Theoretically in this case we could unwrap the <p>: <$root>x[]<p>{}y</p></$root>, but we don't need to support it yet
	// so let's just abort.

Why is this applying only to the root? As the comment says, it's the situation in the current state of implementation when we didn't have limit elements. Now we have them and the endParent is one of them. Also, the $root is actually a limit too.

So, in short, the check could be changed to:

if ( writer.model.schema.isLimit( startParent ) || writer.model.schema.isLimit( endParent ) ) {

The comment needs to be updated a bit too. It seems to cover the raported scenario. However, I'd like to see more tests with deeper nested blocks. Like, if there were several <bQ> elements one in another.

@pomek
Copy link
Member Author

pomek commented Oct 5, 2018

Seems to work. Thx.

@Reinmar Reinmar merged commit 5d26bc3 into master Oct 26, 2018
@Reinmar Reinmar deleted the t/ckeditor5/1265 branch October 26, 2018 09:31
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants