8
0
Просмотр исходного кода

Merge pull request #72 from ckeditor/t/69

Feature: Provide support for pasting lists from Google Docs. Closes #69.
Maciej 6 лет назад
Родитель
Сommit
0e9a9c88ab
25 измененных файлов с 368 добавлено и 10 удалено
  1. 85 1
      packages/ckeditor5-paste-from-office/src/filters/list.js
  2. 3 0
      packages/ckeditor5-paste-from-office/src/normalizers/googledocsnormalizer.js
  3. 43 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/index.js
  4. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/input.html
  5. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/mixed-list.html
  6. 1 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/model.html
  7. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/normalized.html
  8. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/input.html
  9. 1 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/model.html
  10. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/nested-ordered-lists.html
  11. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/normalized.html
  12. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/input.html
  13. 1 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/model.html
  14. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/normalized.html
  15. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/partially-selected.html
  16. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/input.html
  17. 1 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/model.html
  18. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/normalized.html
  19. 0 0
      packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/repeatedly-nested-list.html
  20. 5 2
      packages/ckeditor5-paste-from-office/tests/_utils/fixtures.js
  21. 18 0
      packages/ckeditor5-paste-from-office/tests/data/integration.js
  22. 14 0
      packages/ckeditor5-paste-from-office/tests/data/normalization.js
  23. 190 2
      packages/ckeditor5-paste-from-office/tests/filters/list.js
  24. 1 0
      packages/ckeditor5-paste-from-office/tests/manual/integration.js
  25. 5 5
      packages/ckeditor5-paste-from-office/tests/pastefromoffice.js

+ 85 - 1
packages/ckeditor5-paste-from-office/src/filters/list.js

@@ -49,6 +49,86 @@ export function transformListItemLikeElementsIntoLists( documentFragment, styles
 	} );
 }
 
+/**
+ * Removes paragraph wrapping content inside a list item.
+ *
+ * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment
+ * @param {module:engine/view/upcastwriter~UpcastWriter} writer
+ */
+export function unwrapParagraphInListItem( documentFragment, writer ) {
+	for ( const value of writer.createRangeIn( documentFragment ) ) {
+		const element = value.item;
+
+		if ( element.is( 'li' ) ) {
+			// Google Docs allows on single paragraph inside LI.
+			const firstChild = element.getChild( 0 );
+
+			if ( firstChild.is( 'p' ) ) {
+				writer.unwrapElement( firstChild );
+			}
+		}
+	}
+}
+
+/**
+ * Fix structure of nested lists to follow HTML guidelines and normalize content in predictable way.
+ *
+ * 1. Move nested lists to have sure that list items are the only children of lists.
+ *
+ *		before:                           after:
+ *		OL                                OL
+ *		|-> LI                            |-> LI
+ *		|-> OL                                |-> OL
+ *		    |-> LI                                |-> LI
+ *
+ * 2. Remove additional indentation which cannot be recreated in HTML structure.
+ *
+ *		before:                           after:
+ *		OL                                OL
+ *		|-> LI                            |-> LI
+ *		    |-> OL                            |-> OL
+ *		        |-> OL                            |-> LI
+ *		        |   |-> OL                        |-> LI
+ *		        |       |-> OL
+ *		        |           |-> LI
+ *		        |-> LI
+ *
+ *		before:                           after:
+ *		OL                                OL
+ *		|-> OL                             |-> LI
+ *		    |-> OL
+ *		         |-> OL
+ *		             |-> LI
+ *
+ * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment
+ * @param {module:engine/view/upcastwriter~UpcastWriter} writer
+ */
+export function fixListIndentation( documentFragment, writer ) {
+	for ( const value of writer.createRangeIn( documentFragment ) ) {
+		const element = value.item;
+
+		// case 1: The previous sibling of a list is a list item.
+		if ( element.is( 'li' ) ) {
+			const next = element.nextSibling;
+
+			if ( next && isList( next ) ) {
+				writer.remove( next );
+				writer.insertChild( element.childCount, next, element );
+			}
+		}
+
+		// case 2: The list is the first child of another list.
+		if ( isList( element ) ) {
+			let firstChild = element.getChild( 0 );
+
+			while ( isList( firstChild ) ) {
+				writer.unwrapElement( firstChild );
+				firstChild = element.getChild( 0 );
+			}
+		}
+	}
+}
+
 // Finds all list-like elements in a given document fragment.
 //
 // @param {module:engine/view/documentfragment~DocumentFragment} documentFragment Document fragment
@@ -228,5 +308,9 @@ function isNewListNeeded( previousItem, currentItem ) {
 	}
 
 	// Even with the same id the list does not have to be continuous (#43).
-	return !previousSibling.is( 'ul' ) && !previousSibling.is( 'ol' );
+	return !isList( previousSibling );
+}
+
+function isList( element ) {
+	return element.is( 'ol' ) || element.is( 'ul' );
 }

+ 3 - 0
packages/ckeditor5-paste-from-office/src/normalizers/googledocsnormalizer.js

@@ -8,6 +8,7 @@
  */
 
 import removeBoldWrapper from '../filters/removeboldwrapper';
+import { unwrapParagraphInListItem, fixListIndentation } from '../filters/list';
 import UpcastWriter from '@ckeditor/ckeditor5-engine/src/view/upcastwriter';
 
 const googleDocsMatch = /id=("|')docs-internal-guid-[-0-9a-f]+("|')/i;
@@ -32,5 +33,7 @@ export default class GoogleDocsNormalizer {
 		const writer = new UpcastWriter();
 
 		removeBoldWrapper( data.content, writer );
+		fixListIndentation( data.content, writer );
+		unwrapParagraphInListItem( data.content, writer );
 	}
 }

+ 43 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/index.js

@@ -0,0 +1,43 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+import nestedOrderedList from './nested-ordered-lists/input.html';
+import nestedOrderedListNormalized from './nested-ordered-lists/normalized.html';
+import nestedOrderedListModel from './nested-ordered-lists/model.html';
+
+import mixedList from './mixed-list/input.html';
+import mixedListNormalized from './mixed-list/normalized.html';
+import mixedListModel from './mixed-list/model.html';
+
+import repeatedlyNestedList from './repeatedly-nested-list/input.html';
+import repeatedlyNestedListNormalized from './repeatedly-nested-list/normalized.html';
+import repeatedlyNestedListModel from './repeatedly-nested-list/model.html';
+
+import partiallySelected from './partially-selected/input.html';
+import partiallySelectedNormalized from './partially-selected/normalized.html';
+import partiallySelectedModel from './partially-selected/model.html';
+
+export const fixtures = {
+	input: {
+		nestedOrderedList,
+		mixedList,
+		repeatedlyNestedList,
+		partiallySelected
+	},
+	normalized: {
+		nestedOrderedList: nestedOrderedListNormalized,
+		mixedList: mixedListNormalized,
+		repeatedlyNestedList: repeatedlyNestedListNormalized,
+		partiallySelected: partiallySelectedNormalized
+	},
+	model: {
+		nestedOrderedList: nestedOrderedListModel,
+		mixedList: mixedListModel,
+		repeatedlyNestedList: repeatedlyNestedListModel,
+		partiallySelected: partiallySelectedModel
+	}
+};
+
+export const browserFixtures = {};

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/input.html


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/mixed-list.html


+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/model.html

@@ -0,0 +1 @@
+<listItem listIndent="0" listType="numbered">1</listItem><listItem listIndent="1" listType="bulleted">A</listItem><listItem listIndent="2" listType="numbered">1</listItem><listItem listIndent="0" listType="numbered">2</listItem><listItem listIndent="0" listType="numbered">3</listItem><listItem listIndent="1" listType="bulleted">A</listItem><listItem listIndent="1" listType="bulleted">B</listItem><listItem listIndent="0" listType="bulleted">A</listItem><listItem listIndent="1" listType="numbered">1</listItem><listItem listIndent="1" listType="numbered">2</listItem>

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/mixed-list/normalized.html


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/input.html


+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/model.html

@@ -0,0 +1 @@
+<listItem listIndent="0" listType="numbered">1</listItem><listItem listIndent="1" listType="numbered">11</listItem><listItem listIndent="2" listType="numbered">111</listItem><listItem listIndent="2" listType="numbered">112</listItem><listItem listIndent="3" listType="numbered">1121</listItem><listItem listIndent="3" listType="numbered">1122</listItem><listItem listIndent="3" listType="numbered">1123</listItem><listItem listIndent="1" listType="numbered">12</listItem><listItem listIndent="2" listType="numbered">121</listItem><listItem listIndent="2" listType="numbered">122</listItem><listItem listIndent="3" listType="numbered">1221</listItem><listItem listIndent="1" listType="numbered">13</listItem><listItem listIndent="0" listType="numbered">2</listItem><listItem listIndent="1" listType="numbered">21</listItem><listItem listIndent="1" listType="numbered">22</listItem><listItem listIndent="2" listType="numbered">221</listItem><listItem listIndent="2" listType="numbered">222</listItem><listItem listIndent="2" listType="numbered">223</listItem><listItem listIndent="3" listType="numbered">2231</listItem><listItem listIndent="0" listType="numbered">3</listItem><listItem listIndent="0" listType="numbered">4</listItem><listItem listIndent="0" listType="numbered">5</listItem><listItem listIndent="1" listType="numbered">51</listItem><listItem listIndent="1" listType="numbered">52</listItem><listItem listIndent="1" listType="numbered">53</listItem><listItem listIndent="2" listType="numbered">531</listItem><listItem listIndent="2" listType="numbered">532</listItem><listItem listIndent="1" listType="numbered">54</listItem><listItem listIndent="1" listType="numbered">55</listItem>

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/nested-ordered-lists.html


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/nested-ordered-lists/normalized.html


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/input.html


+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/model.html

@@ -0,0 +1 @@
+<listItem listIndent="0" listType="numbered">F5</listItem><listItem listIndent="0" listType="numbered">G3</listItem><listItem listIndent="0" listType="numbered">H3</listItem><listItem listIndent="1" listType="numbered">I4</listItem><listItem listIndent="2" listType="numbered">J4</listItem><listItem listIndent="0" listType="numbered">K1</listItem><listItem listIndent="1" listType="numbered">L5</listItem><listItem listIndent="1" listType="numbered">M4</listItem><listItem listIndent="1" listType="numbered">N3</listItem><listItem listIndent="1" listType="numbered">O2</listItem>

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/normalized.html


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/partially-selected/partially-selected.html


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/input.html


+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/model.html

@@ -0,0 +1 @@
+<listItem listIndent="0" listType="numbered">A1</listItem><listItem listIndent="1" listType="numbered">B8</listItem><listItem listIndent="1" listType="numbered">C3</listItem><listItem listIndent="2" listType="numbered">D4</listItem><listItem listIndent="1" listType="numbered">E2</listItem>

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/normalized.html


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/lists/repeatedly-nested-list/repeatedly-nested-list.html


+ 5 - 2
packages/ckeditor5-paste-from-office/tests/_utils/fixtures.js

@@ -11,6 +11,7 @@ import { fixtures as list, browserFixtures as listBrowser } from '../_data/list/
 import { fixtures as spacing, browserFixtures as spacingBrowser } from '../_data/spacing/index.js';
 import { fixtures as googleDocsBoldWrapper, browserFixtures as googleDocsBoldWrapperBrowser }
 	from '../_data/paste-from-google-docs/bold-wrapper/index';
+import { fixtures as googleDocsList, browserFixtures as googleDocsListBrowser } from '../_data/paste-from-google-docs/lists/index.js';
 
 // Generic fixtures.
 export const fixtures = {
@@ -19,7 +20,8 @@ export const fixtures = {
 	link,
 	list,
 	spacing,
-	'google-docs-bold-wrapper': googleDocsBoldWrapper
+	'google-docs-bold-wrapper': googleDocsBoldWrapper,
+	'google-docs-list': googleDocsList
 };
 
 // Browser specific fixtures.
@@ -29,5 +31,6 @@ export const browserFixtures = {
 	link: linkBrowser,
 	list: listBrowser,
 	spacing: spacingBrowser,
-	'google-docs-bold-wrapper': googleDocsBoldWrapperBrowser
+	'google-docs-bold-wrapper': googleDocsBoldWrapperBrowser,
+	'google-docs-list': googleDocsListBrowser
 };

+ 18 - 0
packages/ckeditor5-paste-from-office/tests/data/integration.js

@@ -91,4 +91,22 @@ describe( 'PasteFromOffice - integration', () => {
 			plugins: [ Clipboard, Paragraph, Bold, PasteFromOffice ]
 		}
 	} );
+
+	generateTests( {
+		input: 'google-docs-list',
+		type: 'integration',
+		browsers,
+		editorConfig: {
+			plugins: [ Clipboard, Paragraph, List, PasteFromOffice ]
+		}
+	} );
+
+	generateTests( {
+		input: 'generic-list-in-table',
+		type: 'integration',
+		browsers,
+		editorConfig: {
+			plugins: [ Clipboard, Paragraph, List, Table, Bold, PasteFromOffice ]
+		}
+	} );
 } );

+ 14 - 0
packages/ckeditor5-paste-from-office/tests/data/normalization.js

@@ -56,4 +56,18 @@ describe( 'PasteFromOffice - normalization', () => {
 		browsers,
 		editorConfig
 	} );
+
+	generateTests( {
+		input: 'google-docs-list',
+		type: 'normalization',
+		browsers,
+		editorConfig
+	} );
+
+	generateTests( {
+		input: 'generic-list-in-table',
+		type: 'normalization',
+		browsers,
+		editorConfig
+	} );
 } );

+ 190 - 2
packages/ckeditor5-paste-from-office/tests/filters/list.js

@@ -6,11 +6,16 @@
 import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';
 import { stringify } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
 import View from '@ckeditor/ckeditor5-engine/src/view/view';
+import UpcastWriter from '@ckeditor/ckeditor5-engine/src/view/upcastwriter';
 
-import { transformListItemLikeElementsIntoLists } from '../../src/filters/list';
+import {
+	transformListItemLikeElementsIntoLists,
+	unwrapParagraphInListItem,
+	fixListIndentation
+} from '../../src/filters/list';
 
 describe( 'PasteFromOffice - filters', () => {
-	describe( 'list', () => {
+	describe( 'list - paste from MS Word', () => {
 		const htmlDataProcessor = new HtmlDataProcessor();
 
 		describe( 'transformListItemLikeElementsIntoLists()', () => {
@@ -67,4 +72,187 @@ describe( 'PasteFromOffice - filters', () => {
 			} );
 		} );
 	} );
+
+	describe( 'list - paste from google docs', () => {
+		const htmlDataProcessor = new HtmlDataProcessor();
+		let writer;
+
+		before( () => {
+			writer = new UpcastWriter();
+		} );
+
+		describe( 'unwrapParagraphInListItem', () => {
+			it( 'should remove paragraph from list item remaining nested elements', () => {
+				const inputData = '<ul><li><p>foo</p></li><li><p><span>bar</span></p></li></ul>';
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				unwrapParagraphInListItem( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal(
+					'<ul><li>foo</li><li><span>bar</span></li></ul>'
+				);
+			} );
+
+			it( 'should remove paragraph from nested list', () => {
+				const inputData = '<ul>' +
+						'<li>' +
+							'<p>one</p>' +
+							'<ol>' +
+								'<li>' +
+									'<p>two</p>' +
+									'<ul>' +
+										'<li>' +
+											'<p>three</p>' +
+										'</li>' +
+									'</ul>' +
+								'</li>' +
+							'</ol>' +
+						'</li>' +
+					'</ul>';
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				unwrapParagraphInListItem( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal(
+					'<ul><li>one<ol><li>two<ul><li>three</li></ul></li></ol></li></ul>'
+				);
+			} );
+
+			it( 'should do nothing for correct lists', () => {
+				const inputData = '<ol><li>foo</li><li>bar<ul><li>baz</li></ul></li></ol>';
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				unwrapParagraphInListItem( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal( '<ol><li>foo</li><li>bar<ul><li>baz</li></ul></li></ol>' );
+			} );
+		} );
+
+		describe( 'fixListIndentation', () => {
+			it( 'should move nested list to previous list item', () => {
+				const inputData = '<ul>' +
+						'<li>one</li>' +
+						'<ul>' +
+							'<li>two</li>' +
+							'<li>three</li>' +
+						'</ul>' +
+						'<li>four</li>' +
+					'</ul>';
+
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				fixListIndentation( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal(
+					'<ul><li>one<ul><li>two</li><li>three</li></ul></li><li>four</li></ul>'
+				);
+			} );
+		} );
+
+		describe( 'repeatedly nested lists are normalized', () => {
+			it( 'should unwrap single nested list', () => {
+				const inputData = '<ul><li>foo</li><ul><ul><ul><ul><li>bar</li></ul></ul></ul></ul></ul>';
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				fixListIndentation( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal(
+					'<ul><li>foo<ul><li>bar</li></ul></li></ul>'
+				);
+			} );
+
+			it( 'should preserve sibling elements in correct relation', () => {
+				const inputData = '<ol>' +
+						'<li>foo</li>' +
+						'<ol>' +
+							'<ol>' +
+								'<ol>' +
+									'<li>one</li>' +
+								'</ol>' +
+								'<li>two</li>' +
+							'</ol>' +
+							'<li>three</li>' +
+							'<ol>' +
+								'<ol>' +
+									'<ol>' +
+										'<li>four</li>' +
+									'</ol>' +
+								'</ol>' +
+							'</ol>' +
+						'</ol>' +
+						'<li>correct' +
+							'<ol>' +
+								'<li>AAA' +
+									'<ol>' +
+										'<li>BBB</li>' +
+										'<li>CCC</li>' +
+									'</ol>' +
+								'</li>' +
+							'</ol>' +
+						'</li>' +
+					'</ol>';
+
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				fixListIndentation( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal(
+					'<ol>' +
+						'<li>foo' +
+							'<ol>' +
+								'<li>one</li>' +
+								'<li>two</li>' +
+								'<li>three' +
+										'<ol>' +
+											'<li>four</li>' +
+										'</ol>' +
+								'</li>' +
+							'</ol>' +
+						'</li>' +
+						'<li>correct' +
+							'<ol>' +
+								'<li>AAA' +
+									'<ol>' +
+										'<li>BBB</li>' +
+										'<li>CCC</li>' +
+									'</ol>' +
+								'</li>' +
+							'</ol>' +
+						'</li>' +
+					'</ol>'
+				);
+			} );
+
+			it( 'should normalize lists which are start from nested elements', () => {
+				const inputData = '<ol>' +
+						'<ol>' +
+							'<ol>' +
+								'<ol>' +
+									'<li>foo</li>' +
+								'</ol>' +
+							'</ol>' +
+						'</ol>' +
+					'</ol>';
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				fixListIndentation( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal( '<ol><li>foo</li></ol>' );
+			} );
+
+			it( 'should normalize 2 sibling list independently', () => {
+				const inputData = '<ol>' +
+						'<li>foo</li>' +
+					'</ol>' +
+					'<ul>' +
+						'<li>bar</li>' +
+					'</ul>';
+				const documentFragment = htmlDataProcessor.toView( inputData );
+
+				fixListIndentation( documentFragment, writer );
+
+				expect( htmlDataProcessor.toData( documentFragment ) ).to.equal( '<ol><li>foo</li></ol><ul><li>bar</li></ul>' );
+			} );
+		} );
+	} );
 } );

+ 1 - 0
packages/ckeditor5-paste-from-office/tests/manual/integration.js

@@ -32,6 +32,7 @@ ClassicEditor
 	} )
 	.then( editor => {
 		window.editor = editor;
+
 		const clipboard = editor.plugins.get( 'Clipboard' );
 
 		editor.editing.view.document.on( 'paste', ( evt, data ) => {

+ 5 - 5
packages/ckeditor5-paste-from-office/tests/pastefromoffice.js

@@ -65,15 +65,15 @@ describe( 'PasteFromOffice', () => {
 		} );
 
 		describe( 'data which should not be marked with flag', () => {
-			it( 'should not process data with regular html', () => {
-				checkInvalidData( '<p>Hello world</p>' );
+			it( 'should process data with regular html', () => {
+				checkNotProcessedData( '<p>Hello world</p>' );
 			} );
 
-			it( 'should not process data with similar headers to MS Word', () => {
-				checkInvalidData( '<meta name=Generator content="Other">' );
+			it( 'should process data with similar headers to MS Word', () => {
+				checkNotProcessedData( '<meta name=Generator content="Other">' );
 			} );
 
-			function checkInvalidData( inputString ) {
+			function checkNotProcessedData( inputString ) {
 				const data = setUpData( inputString );
 				const getDataSpy = sinon.spy( data.dataTransfer, 'getData' );
 

Некоторые файлы не были показаны из-за большого количества измененных файлов