Krzysztof Krztoń пре 7 година
родитељ
комит
f518b2571f
1 измењених фајлова са 31 додато и 19 уклоњено
  1. 31 19
      packages/ckeditor5-paste-from-office/src/filters/list.js

+ 31 - 19
packages/ckeditor5-paste-from-office/src/filters/list.js

@@ -36,32 +36,42 @@ export function transformListItemLikeElementsIntoLists( documentFragment, styles
 	let currentList = null;
 
 	itemLikeElements.forEach( ( itemLikeElement, i ) => {
-		const isDifferentList = isNewListNeeded( itemLikeElements[ i - 1 ], itemLikeElement );
-		const previousListItem = isDifferentList ? null : itemLikeElements[ i - 1 ];
-		const indentationDifference = getIndentationDifference( previousListItem, itemLikeElement );
+		const isDifferentList = belongsToTheSameList( itemLikeElements[ i - 1 ], itemLikeElement );
+		const previousItemLikeElement = isDifferentList ? null : itemLikeElements[ i - 1 ];
+		const indentationDifference = getIndentationDifference( previousItemLikeElement, itemLikeElement );
 
+		// If item from a new list is encountered, reset "currentList" which points to a previous list element.
 		if ( isDifferentList ) {
 			currentList = null;
 		}
 
-		if ( !currentList || isDifferentList || indentationDifference !== 0 ) {
+		if ( !currentList || indentationDifference !== 0 ) {
 			const listStyle = detectListStyle( itemLikeElement, stylesString );
 
+			// Current list item has indentation level lower than the previous item.
+			// Find the list element with correct indentation level where current list item should be inserted.
 			if ( indentationDifference < 0 ) {
 				currentList = findParentListAtLevel( currentList, indentationDifference );
 
+				// List might have been inserted with different list style (triggered by the item nested inside
+				// it with different list style) so it should be adjusted to the current list item style.
 				if ( !currentList.is( listStyle.type ) ) {
 					currentList = writer.rename( listStyle.type, currentList );
 				}
+			// Current list item has indentation level greater than the previous item. Insert correctly nested new list.
 			} else if ( indentationDifference > 0 ) {
 				if ( currentList ) {
 					const lastListItem = currentList.getChild( currentList.childCount - 1 );
 					const lastListItemChild = lastListItem.getChild( lastListItem.childCount - 1 );
-					currentList = insertNewEmptyList( listStyle, lastListItemChild, writer, indentationDifference );
+
+					// Insert new list element on the end of the last list item in the current list. Since new list element
+					// will be inserted inside list item we need one level less of nesting ("indentationDifference - 1").
+					currentList = insertNewEmptyList( listStyle, lastListItemChild, writer, indentationDifference - 1 );
 				} else {
 					// First item in the list has indentation.
-					currentList = insertNewEmptyList( listStyle, itemLikeElement.element, writer, indentationDifference + 1 );
+					currentList = insertNewEmptyList( listStyle, itemLikeElement.element, writer, indentationDifference );
 				}
+			// Current list item (itemLikeElement) has indentation level the same as previous item.
 			} else {
 				currentList = insertNewEmptyList( listStyle, itemLikeElement.element, writer );
 			}
@@ -180,10 +190,11 @@ function detectListStyle( listLikeItem, stylesString ) {
 //
 // @param {Object} listStyle List style object which determines the type of newly created list.
 // Usually a result of `detectListStyle()` function.
-// @param {module:engine/view/element~Element} element Element before which list is inserted.
+// @param {module:engine/view/element~Element} element Element after which list is inserted.
 // @param {module:engine/view/upcastwriter~UpcastWriter} writer
+// @param {Number} [wrap=0] How many times new empty list element should be wrapped into another list to created nested structure.
 // @returns {module:engine/view/element~Element} Newly created list element.
-function insertNewEmptyList( listStyle, element, writer, indentLevel = 0 ) {
+function insertNewEmptyList( listStyle, element, writer, wrap = 0 ) {
 	const parent = element.parent;
 	const list = writer.createElement( listStyle.type );
 	const position = parent.getChildIndex( element ) + 1;
@@ -191,8 +202,8 @@ function insertNewEmptyList( listStyle, element, writer, indentLevel = 0 ) {
 	let currentList = list;
 
 	// Wrap new list into li's depending on indentation level.
-	if ( indentLevel > 1 ) {
-		for ( let i = 1; i < indentLevel; i++ ) {
+	if ( wrap > 0 ) {
+		for ( let i = 0; i < wrap; i++ ) {
 			const parentList = new Element( listStyle.type );
 			const parentLi = new Element( 'li' );
 			writer.appendChild( currentList, parentLi );
@@ -281,7 +292,7 @@ function removeBulletElement( element, writer ) {
 // @param {Object} previousItem
 // @param {Object} currentItem
 // @returns {Boolean}
-function isNewListNeeded( previousItem, currentItem ) {
+function belongsToTheSameList( previousItem, currentItem ) {
 	if ( !previousItem ) {
 		return true;
 	}
@@ -304,7 +315,8 @@ function isList( element ) {
 	return element.is( 'ol' ) || element.is( 'ul' );
 }
 
-// Calculates the indentation difference between two given list items.
+// Calculates the indentation difference between two given list items (based on indent attribute
+// extracted from `mso-list` style, see #getListItemData).
 //
 // @param {Object} previousItem
 // @param {Object} currentItem
@@ -313,13 +325,13 @@ function getIndentationDifference( previousItem, currentItem ) {
 	return previousItem ? currentItem.indent - previousItem.indent : currentItem.indent - 1;
 }
 
-// Finds parent list of a given list with indentation level lower by a given value.
+// Finds parent list element (ul/ol) of a given list element with indentation level lower by a given value.
 //
-// @param {module:engine/view/element~Element} currentList List element from which to start looking for a parent list.
-// @param {Number} levelDifference Level difference between lists.
-// @returns {module:engine/view/element~Element} Found list.
-function findParentListAtLevel( currentList, levelDifference ) {
-	const ancestors = currentList.getAncestors( { parentFirst: true } );
+// @param {module:engine/view/element~Element} listElement List element from which to start looking for a parent list.
+// @param {Number} indentationDifference Indentation difference between lists.
+// @returns {module:engine/view/element~Element} Found list element with indentation level lower by a given value.
+function findParentListAtLevel( listElement, indentationDifference ) {
+	const ancestors = listElement.getAncestors( { parentFirst: true } );
 
 	let parentList = null;
 	let levelChange = 0;
@@ -329,7 +341,7 @@ function findParentListAtLevel( currentList, levelDifference ) {
 			levelChange--;
 		}
 
-		if ( levelChange === levelDifference ) {
+		if ( levelChange === indentationDifference ) {
 			parentList = ancestor;
 			break;
 		}