Skip to content
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

Fix overwriting text on paste #4356

Merged
merged 11 commits into from
Mar 17, 2021
Merged

Fix overwriting text on paste #4356

merged 11 commits into from
Mar 17, 2021

Conversation

Comandeer
Copy link
Member

What is the purpose of this pull request?

Bug fix

Does your PR contain necessary tests?

All patches that change the editor code must include tests. You can always read more
on PR testing,
how to set the testing environment and
how to create tests
in the official CKEditor documentation.

This PR contains

  • Unit tests
  • Manual tests

Did you follow the CKEditor 4 code style guide?

Your code should follow the guidelines from the CKEditor 4 code style guide which helps keep the entire codebase consistent.

  • PR is consistent with the code style guide

What is the proposed changelog entry for this pull request?

* [#4301](https://github.com/ckeditor/ckeditor4/issues/4301): Fixed: pasted content overwritten when pasted in initially empty editor with [`div` enter mode](https://ckeditor.com/docs/ckeditor4/latest/features/enterkey.html).

What changes did you make?

I've removed the invocation of getData() and replaced it with direct checking of editable's HTML.

Which issues does your PR resolve?

Closes #4301.

@github-actions
Copy link

It's been a while since we last heard from you. We are marking this pull request as stale due to inactivity. Please provide the requested feedback or the pull request will be closed after next 7 days.

@github-actions github-actions bot added the stale The issue / PR will be closed within the next 7 days of inactivity. label Nov 11, 2020
@jacekbogdanski jacekbogdanski self-assigned this Nov 12, 2020
@jacekbogdanski
Copy link
Member

Rebased onto the latest master.

Copy link
Member

@jacekbogdanski jacekbogdanski left a comment

Choose a reason for hiding this comment

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

Looks good, just some minor changes.

core/editable.js Outdated
// Instead of getData method, we directly check the HTML
// due to the fact that interal getData operates on latest snapshot,
// not the current content (#4301).
isEmptyEditable = html === '' || html.match( emptyParagraphRegexp );
Copy link
Member

Choose a reason for hiding this comment

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

Is the emptyParagraphRegexp check here because it's still possible to omit upcasting p to div with unfiltered_html option? If so, we need unit tests covering this case. Not sure if it's possible to do it manually. Did you manage to reproduce with normal editor usage?

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually emptyParagraphRegexp searches for empty div, p and several other elements. It's not a paragraph as an element, but just as a block of text.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for explaining that, but still we are missing unit and manual tests for that case. I just wanted to add them quickly during this review, but find out that I'm actually not able to create any easily reproducible test case for that scenario. Could you update your PR with these tests for empty container elements? If it's just defensive programming, it would be still good to have some spying tests instead.

core/editable.js Show resolved Hide resolved
@github-actions github-actions bot removed the stale The issue / PR will be closed within the next 7 days of inactivity. label Nov 13, 2020
@Comandeer Comandeer self-assigned this Nov 17, 2020
@jacekbogdanski jacekbogdanski self-assigned this Nov 20, 2020
Copy link
Member

@jacekbogdanski jacekbogdanski left a comment

Choose a reason for hiding this comment

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

I see that test /tests/core/editable/manual/enterdiv is failing on Chrome - but it seems like it's also failing on master branch. Not sure if the test started to failing or it has been poorly written. Maybe do you remember @Comandeer how this test should behave?

core/editable.js Outdated
// Instead of getData method, we directly check the HTML
// due to the fact that interal getData operates on latest snapshot,
// not the current content (#4301).
isEmptyEditable = html === '' || html.match( emptyParagraphRegexp );
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for explaining that, but still we are missing unit and manual tests for that case. I just wanted to add them quickly during this review, but find out that I'm actually not able to create any easily reproducible test case for that scenario. Could you update your PR with these tests for empty container elements? If it's just defensive programming, it would be still good to have some spying tests instead.

@github-actions
Copy link

It's been a while since we last heard from you. We are marking this pull request as stale due to inactivity. Please provide the requested feedback or the pull request will be closed after next 7 days.

@github-actions github-actions bot added the stale The issue / PR will be closed within the next 7 days of inactivity. label Nov 28, 2020
@Comandeer Comandeer self-assigned this Nov 30, 2020
@Comandeer
Copy link
Member Author

I see that test /tests/core/editable/manual/enterdiv is failing on Chrome - but it seems like it's also failing on master branch. Not sure if the test started to failing or it has been poorly written.

In fact it was a regression introduced in #3380. Unit tests didn't check for it. I've added the missing test and fixed the current solution to include the case.

I've also added tests for empty paragraph regex.

@github-actions github-actions bot removed the stale The issue / PR will be closed within the next 7 days of inactivity. label Dec 2, 2020
@jacekbogdanski jacekbogdanski self-assigned this Dec 7, 2020
Copy link
Member

@jacekbogdanski jacekbogdanski left a comment

Choose a reason for hiding this comment

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

The test /tests/core/editable/manual/enterdiv is still failing on Firefox, IE (not all editors).

If we've introduced regression recently and it has been already published, we should create a separate ticket for that. Could you do it with some explanation of why the regression happened, as you already checked it out and have more knowledge on the topic?

Comment on lines +110 to +127
return CKEDITOR.tools.array.reduce( tags, function( tests, tag ) {
var tagTests = CKEDITOR.tools.array.reduce( contents, function( tests, content ) {
var test = {};

listener.removeListener();
spy.restore();
test[ 'empty paragraph test: ' + tag + ' with ' + CKEDITOR.tools.htmlEncode( content ) ] = function( editor ) {
var html = '<div>foo</div><div>bar</div>';

assert.areSame( expectedGetDataCount, spy.callCount, 'getData count' );
assert.areSame( 0, i, 'beforeGetData count' );
} );
};
editor.editable().setHtml( generateEmptyParagraph( tag, content ) );
editor.insertHtml( html );

assert.areSame( html, editor.getData() );
};

return CKEDITOR.tools.object.merge( tests, test );
}, {} );

return CKEDITOR.tools.object.merge( tests, tagTests );
}, {} );
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this test generation code would be a bit more readable if we would extract the cartesian product as a separate helper function? So we could just write cartesianProduct( arr1, arr2 ) producing e.g. array-based tuple?

Copy link
Member

Choose a reason for hiding this comment

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

After a second thought, it probably doesn't make much sense as the code is readable enough. Otherwise, we would have to avoid changing tests state directly which may complicate this test further.

@f1ames
Copy link
Contributor

f1ames commented Dec 10, 2020

@Comandeer, @jacekbogdanski when you will be ready with this PR let's ask @ckeditor/qa-team (@LukaszGudel) to check it too 👍

@github-actions
Copy link

It's been a while since we last heard from you. We are marking this pull request as stale due to inactivity. Please provide the requested feedback or the pull request will be closed after next 7 days.

@jacekbogdanski
Copy link
Member

I did some wrap up about the whole issue with the current implementation, so we can finally proceed with this PR:

  1. The first fix was for Editor with enterMode set to ENTER_DIV alters content on paste #2751, but
    1. We introduced a regression for Incorrect getData event during dropping content into editable #3379
    2. It didn't totally fix the issue. Some cases like selecting all content with the mouse (not ctrl+A) don't work correctly e.g. on IE11
  2. We did fix for Incorrect getData event during dropping content into editable #3379, but
    1. We introduced a regression for 4.15.0 - Paste overwrites existing text #4301
  3. We are here now, fixing 4.15.0 - Paste overwrites existing text #4301, but
    1. We experienced all additional edge cases not fixed by partial Editor with enterMode set to ENTER_DIV alters content on paste #2751 fix.

The best approach would be revisiting #2751 and going with the proper fix in the first place. However, since the proper fix may not be trivial and the current issue looks like something which may occur much more often when using the editor, I would be for keeping the current fix and extracting the proper solution as a separate ticket. To compare issues:

  • Fix in Editor with enterMode set to ENTER_DIV alters content on paste #2751 - is partial and is not covering cases when whole editor selection is made by a mouse due to different selection anchors. Results in incorrectly wrapped HTML with redundant elements.
  • Current fix - fixes the case when pasting the same text again into the empty editor results in losing pasted data.

So, it makes more sense to go with the current workaround (since it's almost finished) and start thinking about a more complicated, general fix for selection (replacing #2751 entirely), then postponing the fix for the current issue and working on a new fix #2751 right now.

I will go with another review round and if there are only minor issues left (like improving tests), we can go with this PR as the current solution.

@github-actions
Copy link

github-actions bot commented Mar 5, 2021

It's been a while since we last heard from you. We are marking this pull request as stale due to inactivity. Please provide the requested feedback or the pull request will be closed after next 7 days.

@github-actions github-actions bot added the stale The issue / PR will be closed within the next 7 days of inactivity. label Mar 5, 2021
@Dumluregn Dumluregn removed the stale The issue / PR will be closed within the next 7 days of inactivity. label Mar 5, 2021
@github-actions
Copy link

It's been a while since we last heard from you. We are marking this pull request as stale due to inactivity. Please provide the requested feedback or the pull request will be closed after next 7 days.

@github-actions github-actions bot added the stale The issue / PR will be closed within the next 7 days of inactivity. label Mar 13, 2021
@Dumluregn Dumluregn removed the stale The issue / PR will be closed within the next 7 days of inactivity. label Mar 15, 2021
@jacekbogdanski jacekbogdanski self-requested a review March 15, 2021 14:33
@jacekbogdanski
Copy link
Member

jacekbogdanski commented Mar 15, 2021

Looks like we are ready for some QA, @ckeditor/qa-team team could you help with testing this fix? We are focused on fixing #4301 but as explained in #4356 (comment) we still may have some issues with invalid div wrapping, but it should not be a part of this PR. I will extract a follow-up in a moment (#4572).

@LukaszGudel
Copy link

LukaszGudel commented Mar 16, 2021

Other than the scenario from this issue (paste some text from outside) I've found three other ways of inserting content to the editor that are also affected by this bug. Additionally, it is possible to:

  • drag and drop some text from outside the editor multiple times
  • insert text using editor.insertHtml('content') multiple times
  • type some text and then copy it and paste at the end multiple times

In all of the above cases the result is the same, only the last one copied/inserted text is showing.


On the t/4301 branch none of those cases produces this issue. I did not find any other issues with empty editor and div_enter.

Copy link
Member

@jacekbogdanski jacekbogdanski left a comment

Choose a reason for hiding this comment

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

Thanks, @LukaszGudel! I see that failing CI is already reported:

#3424
#3868

Good job @Comandeer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants