Skip to content

Commit

Permalink
Merge pull request #17222 from ckeditor/ck/1944-bookmark-insert-parag…
Browse files Browse the repository at this point in the history
…raph-fix

Fix (list): Inserting or dropping a paragraph after the end of a list should not convert the paragraph to a list item. Closes #17224.
  • Loading branch information
niegowski authored Oct 4, 2024
2 parents f9ad029 + d471196 commit 77d5f08
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/ckeditor5-list/src/list/listediting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ function createModelIndentPasteFixer( model: Model ): GetCallback<ModelInsertCon

if ( isListItemBlock( position.parent ) ) {
refItem = position.parent;
} else if ( isListItemBlock( position.nodeBefore ) ) {
} else if ( isListItemBlock( position.nodeBefore ) && isListItemBlock( position.nodeAfter ) ) {
refItem = position.nodeBefore;
} else {
return; // Content is not copied into a list.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ describe( 'ListEditing (multiBlock=false) integrations: clipboard copy & paste',
} ).not.to.throw();
} );

it( 'should correctly handle item that is pasted without its parent', () => {
it( 'should correctly handle item that is pasted between list items without its parent', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
Expand All @@ -409,6 +409,7 @@ describe( 'ListEditing (multiBlock=false) integrations: clipboard copy & paste',
'<listItem listType="numbered" listItemId="a" listIndent="0">A</listItem>' +
'<listItem listType="numbered" listItemId="b" listIndent="1">B</listItem>' +
'[]' +
'<listItem listType="numbered" listItemId="c" listIndent="1">C</listItem>' +
'<paragraph>Bar</paragraph>'
);

Expand All @@ -424,11 +425,12 @@ describe( 'ListEditing (multiBlock=false) integrations: clipboard copy & paste',
'<listItem listIndent="0" listItemId="a" listType="numbered">A</listItem>' +
'<listItem listIndent="1" listItemId="b" listType="numbered">B</listItem>' +
'<listItem listIndent="1" listItemId="a00" listType="numbered">X[]</listItem>' +
'<listItem listIndent="1" listItemId="c" listType="numbered">C</listItem>' +
'<paragraph>Bar</paragraph>'
);
} );

it( 'should correctly handle item that is pasted without its parent #2', () => {
it( 'should correctly handle item that is pasted between list items without its parent #2', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
Expand All @@ -437,6 +439,7 @@ describe( 'ListEditing (multiBlock=false) integrations: clipboard copy & paste',
'<listItem listType="numbered" listItemId="a" listIndent="0">A</listItem>' +
'<listItem listType="numbered" listItemId="b" listIndent="1">B</listItem>' +
'[]' +
'<listItem listType="numbered" listItemId="c" listIndent="1">C</listItem>' +
'<paragraph>Bar</paragraph>'
);

Expand All @@ -453,6 +456,64 @@ describe( 'ListEditing (multiBlock=false) integrations: clipboard copy & paste',
'<listItem listIndent="1" listItemId="b" listType="numbered">B</listItem>' +
'<listItem listIndent="1" listItemId="a01" listType="numbered">X</listItem>' +
'<listItem listIndent="2" listItemId="a00" listType="numbered">Y[]</listItem>' +
'<listItem listIndent="1" listItemId="c" listType="numbered">C</listItem>' +
'<paragraph>Bar</paragraph>'
);
} );

it( 'should correctly handle item that is pasted after last list item without its parent', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
setModelData( model,
'<paragraph>Foo</paragraph>' +
'<listItem listType="numbered" listItemId="a" listIndent="0">A</listItem>' +
'<listItem listType="numbered" listItemId="b" listIndent="1">B</listItem>' +
'[]' +
'<paragraph>Bar</paragraph>'
);

const clipboard = editor.plugins.get( 'ClipboardPipeline' );

clipboard.fire( 'inputTransformation', {
content: parseView( '<li>X</li>' )
} );
} );

expect( getModelData( model ) ).to.equalMarkup(
'<paragraph>Foo</paragraph>' +
'<listItem listIndent="0" listItemId="a" listType="numbered">A</listItem>' +
'<listItem listIndent="1" listItemId="b" listType="numbered">B</listItem>' +
'<listItem listIndent="0" listItemId="a00" listType="bulleted">X[]</listItem>' +
'<paragraph>Bar</paragraph>'
);
} );

it( 'should correctly handle item that is pasted after last list item without its parent #2', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
setModelData( model,
'<paragraph>Foo</paragraph>' +
'<listItem listType="numbered" listItemId="a" listIndent="0">A</listItem>' +
'<listItem listType="numbered" listItemId="b" listIndent="1">B</listItem>' +
'[]' +
'<paragraph>Bar</paragraph>'
);

const clipboard = editor.plugins.get( 'ClipboardPipeline' );

clipboard.fire( 'inputTransformation', {
content: parseView( '<li>X<ul><li>Y</li></ul></li>' )
} );
} );

expect( getModelData( model ) ).to.equalMarkup(
'<paragraph>Foo</paragraph>' +
'<listItem listIndent="0" listItemId="a" listType="numbered">A</listItem>' +
'<listItem listIndent="1" listItemId="b" listType="numbered">B</listItem>' +
'<listItem listIndent="0" listItemId="a01" listType="bulleted">X</listItem>' +
'<listItem listIndent="1" listItemId="a00" listType="bulleted">Y[]</listItem>' +
'<paragraph>Bar</paragraph>'
);
} );
Expand Down
61 changes: 59 additions & 2 deletions packages/ckeditor5-list/tests/list/integrations/clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ describe( 'ListEditing integrations: clipboard copy & paste', () => {
} ).not.to.throw();
} );

it( 'should correctly handle item that is pasted without its parent', () => {
it( 'should correctly handle item that is pasted between list items without its parent', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
Expand All @@ -573,6 +573,7 @@ describe( 'ListEditing integrations: clipboard copy & paste', () => {
'<paragraph listType="numbered" listItemId="a" listIndent="0">A</paragraph>' +
'<paragraph listType="numbered" listItemId="b" listIndent="1">B</paragraph>' +
'[]' +
'<paragraph listType="numbered" listItemId="c" listIndent="1">C</paragraph>' +
'<paragraph>Bar</paragraph>'
);

Expand All @@ -586,11 +587,12 @@ describe( 'ListEditing integrations: clipboard copy & paste', () => {
'<paragraph listIndent="0" listItemId="a" listType="numbered">A</paragraph>' +
'<paragraph listIndent="1" listItemId="b" listType="numbered">B</paragraph>' +
'<paragraph listIndent="1" listItemId="a00" listType="numbered">X[]</paragraph>' +
'<paragraph listIndent="1" listItemId="c" listType="numbered">C</paragraph>' +
'<paragraph>Bar</paragraph>'
);
} );

it( 'should correctly handle item that is pasted without its parent #2', () => {
it( 'should correctly handle item that is pasted between list items without its parent #2', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
Expand All @@ -599,6 +601,7 @@ describe( 'ListEditing integrations: clipboard copy & paste', () => {
'<paragraph listType="numbered" listItemId="a" listIndent="0">A</paragraph>' +
'<paragraph listType="numbered" listItemId="b" listIndent="1">B</paragraph>' +
'[]' +
'<paragraph listType="numbered" listItemId="c" listIndent="1">C</paragraph>' +
'<paragraph>Bar</paragraph>'
);

Expand All @@ -613,6 +616,60 @@ describe( 'ListEditing integrations: clipboard copy & paste', () => {
'<paragraph listIndent="1" listItemId="b" listType="numbered">B</paragraph>' +
'<paragraph listIndent="1" listItemId="a01" listType="numbered">X</paragraph>' +
'<paragraph listIndent="2" listItemId="a00" listType="numbered">Y[]</paragraph>' +
'<paragraph listIndent="1" listItemId="c" listType="numbered">C</paragraph>' +
'<paragraph>Bar</paragraph>'
);
} );

it( 'should correctly handle item that is pasted after last list item without its parent', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
setModelData( model,
'<paragraph>Foo</paragraph>' +
'<paragraph listType="numbered" listItemId="a" listIndent="0">A</paragraph>' +
'<paragraph listType="numbered" listItemId="b" listIndent="1">B</paragraph>' +
'[]' +
'<paragraph>Bar</paragraph>'
);

clipboard.fire( 'inputTransformation', {
content: parseView( '<li>X</li>' )
} );
} );

expect( getModelData( model ) ).to.equalMarkup(
'<paragraph>Foo</paragraph>' +
'<paragraph listIndent="0" listItemId="a" listType="numbered">A</paragraph>' +
'<paragraph listIndent="1" listItemId="b" listType="numbered">B</paragraph>' +
'<paragraph listIndent="0" listItemId="a00" listType="bulleted">X[]</paragraph>' +
'<paragraph>Bar</paragraph>'
);
} );

it( 'should correctly handle item that is pasted after last list item without its parent #2', () => {
// Wrap all changes in one block to avoid post-fixing the selection
// (which may be incorret) in the meantime.
model.change( () => {
setModelData( model,
'<paragraph>Foo</paragraph>' +
'<paragraph listType="numbered" listItemId="a" listIndent="0">A</paragraph>' +
'<paragraph listType="numbered" listItemId="b" listIndent="1">B</paragraph>' +
'[]' +
'<paragraph>Bar</paragraph>'
);

clipboard.fire( 'inputTransformation', {
content: parseView( '<li>X<ul><li>Y</li></ul></li>' )
} );
} );

expect( getModelData( model ) ).to.equalMarkup(
'<paragraph>Foo</paragraph>' +
'<paragraph listIndent="0" listItemId="a" listType="numbered">A</paragraph>' +
'<paragraph listIndent="1" listItemId="b" listType="numbered">B</paragraph>' +
'<paragraph listIndent="0" listItemId="a01" listType="bulleted">X</paragraph>' +
'<paragraph listIndent="1" listItemId="a00" listType="bulleted">Y[]</paragraph>' +
'<paragraph>Bar</paragraph>'
);
} );
Expand Down
6 changes: 4 additions & 2 deletions tests/manual/all-features-dll.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import '@ckeditor/ckeditor5-editor-balloon/build/editor-balloon.js';
// Plugins.
import '@ckeditor/ckeditor5-image/build/image.js';
import '@ckeditor/ckeditor5-link/build/link.js';
import '@ckeditor/ckeditor5-bookmark/build/bookmark.js';
import '@ckeditor/ckeditor5-basic-styles/build/basic-styles.js';
import '@ckeditor/ckeditor5-find-and-replace/build/find-and-replace.js';
import '@ckeditor/ckeditor5-font/build/font.js';
Expand Down Expand Up @@ -53,6 +54,7 @@ const { BalloonEditor } = window.CKEditor5.editorBalloon;

const { AutoImage, Image, ImageCaption, ImageResize, ImageStyle, ImageToolbar, ImageUpload } = window.CKEditor5.image;
const { AutoLink, Link, LinkImage } = window.CKEditor5.link;
const { Bookmark } = window.CKEditor5.bookmark;
const { Bold, Italic, Strikethrough, Subscript, Superscript, Underline, Code } = window.CKEditor5.basicStyles;
const { FindAndReplace } = window.CKEditor5.findAndReplace;
const { FontColor, FontFamily, FontSize, FontBackgroundColor } = window.CKEditor5.font;
Expand Down Expand Up @@ -113,7 +115,7 @@ const config = {
Alignment,
Autoformat,
AutoImage, Image, ImageCaption, ImageResize, ImageStyle, ImageToolbar, ImageUpload,
AutoLink, Link, LinkImage,
AutoLink, Link, LinkImage, Bookmark,
BlockQuote,
Bold, Italic, Strikethrough, Subscript, Superscript, Underline, Code,
CloudServices,
Expand Down Expand Up @@ -145,7 +147,7 @@ const config = {
'|',
'ad-hoc-button',
'|',
'removeFormat', 'bold', 'italic', 'strikethrough', 'underline', 'code', 'subscript', 'superscript', 'link',
'removeFormat', 'bold', 'italic', 'strikethrough', 'underline', 'code', 'subscript', 'superscript', 'link', 'bookmark',
'|',
'highlight', 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor',
'|',
Expand Down
4 changes: 2 additions & 2 deletions tests/manual/all-features.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ <h2>Lists in the table</h2>
</table>
</figure>

<h2>Basic features overview</h2>
<h2><a id="basic-features-overview"></a>Basic features overview</h2>
<p>Lorem <b>ipsum dolor sit </b>amet, consectetur <i>adipisicing elit</i>.<sub>1</sub></p>
<h3>Basic styles</h3>
<p>Ad alias, <s>architecto</s> culpa <b><i>cumque</i></b> dignissimos <code>dolor eos incidunt ipsa itaque</code> <u>laboriosam</u> magnam molestias nihil <i><u>numquam</u></i> odit quam, suscipit <i><s>veritatis</s></i> voluptate voluptatum.<sup>2</sup></p>
<p><a id="in-text-bookmark"></a>Ad alias, <s>architecto</s> culpa <b><i>cumque</i></b> dignissimos <code>dolor eos incidunt ipsa itaque</code> <u>laboriosam</u> magnam molestias nihil <i><u>numquam</u></i> odit quam, suscipit <i><s>veritatis</s></i> voluptate voluptatum.<sup>2</sup></p>
<h3>Image</h3>
<figure class="image">
<img alt="bar" src="sample.jpg">
Expand Down
5 changes: 3 additions & 2 deletions tests/manual/all-features.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import WordCount from '@ckeditor/ckeditor5-word-count/src/wordcount.js';
import CloudServices from '@ckeditor/ckeditor5-cloud-services/src/cloudservices.js';
import Style from '@ckeditor/ckeditor5-style/src/style.js';
import GeneralHtmlSupport from '@ckeditor/ckeditor5-html-support/src/generalhtmlsupport.js';
import Bookmark from '@ckeditor/ckeditor5-bookmark/src/bookmark.js';

import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config.js';

Expand All @@ -61,15 +62,15 @@ ClassicEditor
CodeBlock, TodoList, ListProperties, TableProperties, TableCellProperties, TableCaption, TableColumnResize,
EasyImage, ImageResize, ImageInsert, LinkImage, AutoImage, HtmlEmbed, HtmlComment,
AutoLink, Mention, TextTransformation,
Alignment, IndentBlock,
Alignment, IndentBlock, Bookmark,
PasteFromOffice, PageBreak, HorizontalLine, ShowBlocks,
SpecialCharacters, SpecialCharactersEssentials, WordCount,
CloudServices, TextPartLanguage, SourceEditing, Style, GeneralHtmlSupport
],
toolbar: [
'heading', 'style',
'|',
'removeFormat', 'bold', 'italic', 'strikethrough', 'underline', 'code', 'subscript', 'superscript', 'link',
'removeFormat', 'bold', 'italic', 'strikethrough', 'underline', 'code', 'subscript', 'superscript', 'link', 'bookmark',
'|',
'highlight', 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor',
'|',
Expand Down

0 comments on commit 77d5f08

Please sign in to comment.