8
0
Kamil Piechaczek 5 лет назад
Родитель
Сommit
5c4c5406ae

+ 66 - 27
packages/ckeditor5-paste-from-office/src/filters/list.js

@@ -51,26 +51,16 @@ export function transformListItemLikeElementsIntoLists( documentFragment, styles
 
 			if ( !currentList ) {
 				currentList = insertNewEmptyList( listStyle, itemLikeElement.element, writer );
-
-				// We do not support modifying the marker for particular list item.
-				// Set the value for the `list-style-type` property directly to the list container.
-				const parsedListStyleValue = mapListStyleDefinition( listStyle.style );
-
-				if ( parsedListStyleValue ) {
-					writer.setStyle( 'list-style-type', parsedListStyleValue, currentList );
-				}
 			} else if ( itemLikeElement.indent > currentIndentation ) {
 				const lastListItem = currentList.getChild( currentList.childCount - 1 );
 				const lastListItemChild = lastListItem.getChild( lastListItem.childCount - 1 );
 
 				currentList = insertNewEmptyList( listStyle, lastListItemChild, writer );
-
 				currentIndentation += 1;
 			} else if ( itemLikeElement.indent < currentIndentation ) {
 				const differentIndentation = currentIndentation - itemLikeElement.indent;
 
 				currentList = findParentListAtLevel( currentList, differentIndentation );
-
 				currentIndentation = parseInt( itemLikeElement.indent );
 			}
 
@@ -166,9 +156,9 @@ function findAllItemLikeElements( documentFragment, writer ) {
 // @param {String} stylesString CSS stylesheet.
 // @returns {Object} result
 // @returns {String} result.type List type, could be `ul` or `ol`.
-// @returns {String} result.style List style, for example: `decimal`, `lower-roman`, etc. It is extracted
-// directly from Word stylesheet without further processing and may be not compatible
-// with CSS `list-style-type` property accepted values.
+// @returns {String|null} result.style List style, for example: `decimal`, `lower-roman`, etc. It is extracted
+// directly from Word stylesheet and adjusted to represent proper values for the CSS `list-style-type` property.
+// If it cannot be adjusted, the `null` value is returned.
 function detectListStyle( listLikeItem, stylesString ) {
 	const listStyleRegexp = new RegExp( `@list l${ listLikeItem.id }:level${ listLikeItem.indent }\\s*({[^}]*)`, 'gi' );
 	const listStyleTypeRegex = /mso-level-number-format:([^;]*);/gi;
@@ -176,6 +166,8 @@ function detectListStyle( listLikeItem, stylesString ) {
 	const listStyleMatch = listStyleRegexp.exec( stylesString );
 
 	let listStyleType = 'decimal'; // Decimal is default one.
+	let type;
+
 	if ( listStyleMatch && listStyleMatch[ 1 ] ) {
 		const listStyleTypeMatch = listStyleTypeRegex.exec( listStyleMatch[ 1 ] );
 
@@ -183,31 +175,72 @@ function detectListStyle( listLikeItem, stylesString ) {
 			listStyleType = listStyleTypeMatch[ 1 ].trim();
 		}
 
+		type = listStyleType !== 'bullet' && listStyleType !== 'image' ? 'ol' : 'ul';
+
 		// Styles for the numbered lists are defined in Word CSS stylesheet.
 		// Bulleted lists are not described and we need to predict the list style value based on
-		// the list style marker.
+		// the list style marker element.
 		if ( listStyleType === 'bullet' ) {
-			const listMarker = listLikeItem.element.getChild( 0 ).getChild( 0 ).getChild( 0 )._data;
-
-			if ( listMarker === 'o' ) {
-				listStyleType = 'circle';
-			} else if ( listMarker === '·' ) {
-				listStyleType = 'disc';
-			} else if ( listMarker === '§' ) {
-				listStyleType = 'square';
+			const bulletedStyle = findBulletedListStyle( listLikeItem.element );
+
+			if ( bulletedStyle ) {
+				listStyleType = bulletedStyle;
 			}
 		}
 	}
 
 	return {
-		type: listStyleType !== 'bullet' && listStyleType !== 'image' ? 'ol' : 'ul',
-		style: listStyleType
+		type,
+		style: mapListStyleDefinition( listStyleType )
 	};
 }
 
-// An object returned by the `detectListStyle()` function contains a definition of the `list-style-type` that could be applied to
-// the created list container. However, it's extracted directly from Word stylesheet without further processing and may be not compatible
-// with the known values for the `list-style-type` property. This function modifies Word-styles to proper CSS definitions.
+// Tries extract the `list-style-type` value based on the marker element for bulleted list.
+//
+// @param {module:engine/view/element~Element} element
+// @returns {module:engine/view/element~Element|null}
+function findBulletedListStyle( element ) {
+	const listMarkerElement = findListMarkerNode( element );
+
+	if ( !listMarkerElement ) {
+		return null;
+	}
+
+	const listMarker = listMarkerElement._data;
+
+	if ( listMarker === 'o' ) {
+		return 'circle';
+	} else if ( listMarker === '·' ) {
+		return 'disc';
+	// Word returns '§' instead of '■' for the square list style.
+	} else if ( listMarker === '§' ) {
+		return 'square';
+	}
+
+	return null;
+}
+
+// Tries to find a text node that represents the marker element (list-style-type).
+//
+// @param {module:engine/view/element~Element} element
+// @returns {module:engine/view/text~Text|null}
+function findListMarkerNode( element ) {
+	let textNodeOrElement = element.getChild( 0 ).getChild( 0 );
+
+	if ( textNodeOrElement.is( '$text' ) ) {
+		return textNodeOrElement;
+	}
+
+	textNodeOrElement = textNodeOrElement.getChild( 0 );
+
+	if ( textNodeOrElement.is( '$text' ) ) {
+		return textNodeOrElement;
+	}
+
+	return null;
+}
+
+// Parses the `list-style-type` value extracted directly from the Word CSS stylesheet and returns proper CSS definition.
 //
 // @param {String|null} value
 // @returns {String|null}
@@ -247,6 +280,12 @@ function insertNewEmptyList( listStyle, element, writer ) {
 
 	writer.insertChild( position, list, parent );
 
+	// We do not support modifying the marker for particular list item.
+	// Set the value for the `list-style-type` property directly to the list container.
+	if ( listStyle.style ) {
+		writer.setStyle( 'list-style-type', listStyle.style, list );
+	}
+
 	return list;
 }
 

+ 8 - 8
packages/ckeditor5-paste-from-office/tests/_data/list/nested-multiple/normalized.safari.word2016.html

@@ -1,7 +1,7 @@
-<ul>
+<ul style="list-style-type:disc">
 	<li class="MsoListParagraphCxSpFirst" style="mso-list:l1 level1 lfo2;text-indent:-18.0pt">
 		<span style="font-family:Symbol;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol"></span>A1<o:p></o:p>
-		<ol>
+		<ol style="list-style-type:square">
 			
           <li class="MsoListParagraphCxSpMiddle" style="margin-left:108.0pt;mso-add-space:auto;mso-list:l1 level3 lfo2;text-indent:-18.0pt">
             <span style="font-family:Wingdings;mso-bidi-font-family:Wingdings;mso-fareast-font-family:Wingdings"></span>B3<o:p></o:p>
@@ -12,20 +12,20 @@
 			</li>
 		</ol>
 	</li>
-</ul>
+</ol>
 
 <p class="MsoNormal" style="-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;caret-color:rgb(0, 0, 0);color:rgb(0, 0, 0);font-family:Calibri, sans-serif;font-size:medium;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;margin:0cm 0cm 0.0001pt;orphans:auto;text-align:start;text-decoration:none;text-indent:0px;text-transform:none;white-space:normal;widows:auto;word-spacing:0px"></p>
 <p class="MsoNormal" style="-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;caret-color:rgb(0, 0, 0);color:rgb(0, 0, 0);font-family:Calibri, sans-serif;font-size:medium;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;margin:0cm 0cm 0.0001pt;orphans:auto;text-align:start;text-decoration:none;text-indent:0px;text-transform:none;white-space:normal;widows:auto;word-spacing:0px">Foo Bar...<o:p></o:p></p>
 <p class="MsoNormal" style="-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;caret-color:rgb(0, 0, 0);color:rgb(0, 0, 0);font-family:Calibri, sans-serif;font-size:medium;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;margin:0cm 0cm 0.0001pt;orphans:auto;text-align:start;text-decoration:none;text-indent:0px;text-transform:none;white-space:normal;widows:auto;word-spacing:0px"></p>
 
-<ol>
+<ol style="list-style-type:lower-alpha">
   <li class="MsoListParagraphCxSpFirst" style="margin-left:72.0pt;mso-add-space:auto;mso-list:l0 level2 lfo1;text-indent:-18.0pt">
     <span style="mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin"></span>A2<o:p></o:p>
   </li>
 
     <li class="MsoListParagraphCxSpMiddle" style="mso-list:l0 level1 lfo1;text-indent:-18.0pt">
 		<span style="mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin"></span>B1<o:p></o:p>
-		<ol>
+		<ol style="list-style-type:lower-alpha">
 			<li class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;mso-list:l0 level2 lfo1;text-indent:-18.0pt">
 				<span style="mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin"></span>C2<o:p></o:p>
 			</li>
@@ -35,10 +35,10 @@
 
 <p class="MsoNormal" style="-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;caret-color:rgb(0, 0, 0);color:rgb(0, 0, 0);font-family:Calibri, sans-serif;font-size:medium;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;margin:0cm 0cm 0.0001pt;orphans:auto;text-align:start;text-decoration:none;text-indent:0px;text-transform:none;white-space:normal;widows:auto;word-spacing:0px"></p>
 
-<ul>
+<ul style="list-style-type:disc">
 	<li class="MsoListParagraphCxSpFirst" style="mso-list:l1 level1 lfo2;text-indent:-18.0pt">
 		<span style="font-family:Symbol;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol"></span>A1<o:p></o:p>
-		<ol>
+		<ol style="list-style-type:square">
 			<li class="MsoListParagraphCxSpMiddle" style="margin-left:72.0pt;mso-add-space:auto;mso-list:l1 level2 lfo2;text-indent:-18.0pt">
 				<span style="mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin"></span>B2<o:p></o:p>
 			</li>
@@ -48,4 +48,4 @@
 	<li class="MsoListParagraphCxSpLast" style="mso-list:l1 level1 lfo2;text-indent:-18.0pt">
 		<span style="font-family:Symbol;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol"></span>C1<o:p></o:p>
 	</li>
-</ul>
+</ol>

+ 5 - 5
packages/ckeditor5-paste-from-office/tests/_data/list/nested-multiple/normalized.word2016.html

@@ -1,7 +1,7 @@
-<ul>
+<ul style="list-style-type:disc">
 	<li class="MsoListParagraphCxSpFirst" style="mso-list:l1 level1 lfo2;text-indent:-18.0pt">
 		<span style="font-family:Symbol;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol"></span>A1<o:p></o:p>
-		<ol>
+		<ol style="list-style-type:square">
           <li class="MsoListParagraphCxSpMiddle" style="margin-left:108.0pt;mso-add-space:auto;mso-list:l1 level3 lfo2;text-indent:-18.0pt">
             <span style="font-family:Wingdings;mso-bidi-font-family:Wingdings;mso-fareast-font-family:Wingdings"></span>B3<o:p></o:p>
           </li>
@@ -17,14 +17,14 @@
 <p class="MsoNormal">Foo Bar...<o:p></o:p></p>
 <p class="MsoNormal"></p>
 
-<ol>
+<ol style="list-style-type:lower-alpha">
   <li class="MsoListParagraphCxSpFirst" style="margin-left:72.0pt;mso-add-space:auto;mso-list:l0 level2 lfo1;text-indent:-18.0pt">
     <span style="mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin"></span>A2<o:p></o:p>
   </li>
 
     <li class="MsoListParagraphCxSpMiddle" style="mso-list:l0 level1 lfo1;text-indent:-18.0pt">
 		<span style="mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin"></span>B1<o:p></o:p>
-		<ol>
+		<ol style="list-style-type:lower-alpha">
 			<li class="MsoListParagraphCxSpLast" style="margin-left:72.0pt;mso-add-space:auto;mso-list:l0 level2 lfo1;text-indent:-18.0pt">
 				<span style="mso-bidi-font-family:Calibri;mso-bidi-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin"></span>C2<o:p></o:p>
 			</li>
@@ -34,7 +34,7 @@
 
 <p class="MsoNormal"></p>
 
-<ul>
+<ul style="list-style-type:disc">
 	<li class="MsoListParagraphCxSpFirst" style="mso-list:l1 level1 lfo2;text-indent:-18.0pt">
 		<span style="font-family:Symbol;mso-bidi-font-family:Symbol;mso-fareast-font-family:Symbol"></span>A1<o:p></o:p>
 		<ol>

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

@@ -15,27 +15,27 @@ const editorConfig = {
 	plugins: [ Clipboard, PasteFromOffice, Paragraph ]
 };
 
-describe( 'PasteFromOffice - normalization', () => {
-	generateTests( {
-		input: 'basic-styles',
-		type: 'normalization',
-		browsers,
-		editorConfig
-	} );
-
-	generateTests( {
-		input: 'image',
-		type: 'normalization',
-		browsers,
-		editorConfig
-	} );
-
-	generateTests( {
-		input: 'link',
-		type: 'normalization',
-		browsers,
-		editorConfig
-	} );
+describe.only( 'PasteFromOffice - normalization', () => {
+	// generateTests( {
+	// 	input: 'basic-styles',
+	// 	type: 'normalization',
+	// 	browsers,
+	// 	editorConfig
+	// } );
+	//
+	// generateTests( {
+	// 	input: 'image',
+	// 	type: 'normalization',
+	// 	browsers,
+	// 	editorConfig
+	// } );
+	//
+	// generateTests( {
+	// 	input: 'link',
+	// 	type: 'normalization',
+	// 	browsers,
+	// 	editorConfig
+	// } );
 
 	generateTests( {
 		input: 'list',
@@ -44,24 +44,24 @@ describe( 'PasteFromOffice - normalization', () => {
 		editorConfig
 	} );
 
-	generateTests( {
-		input: 'spacing',
-		type: 'normalization',
-		browsers,
-		editorConfig
-	} );
-
-	generateTests( {
-		input: 'google-docs-bold-wrapper',
-		type: 'normalization',
-		browsers,
-		editorConfig
-	} );
-
-	generateTests( {
-		input: 'generic-list-in-table',
-		type: 'normalization',
-		browsers,
-		editorConfig
-	} );
+	// generateTests( {
+	// 	input: 'spacing',
+	// 	type: 'normalization',
+	// 	browsers,
+	// 	editorConfig
+	// } );
+	//
+	// generateTests( {
+	// 	input: 'google-docs-bold-wrapper',
+	// 	type: 'normalization',
+	// 	browsers,
+	// 	editorConfig
+	// } );
+	//
+	// generateTests( {
+	// 	input: 'generic-list-in-table',
+	// 	type: 'normalization',
+	// 	browsers,
+	// 	editorConfig
+	// } );
 } );

+ 4 - 1
tests/manual/all-features.js

@@ -36,6 +36,8 @@ import ImageResize from '@ckeditor/ckeditor5-image/src/imageresize';
 import LinkImage from '@ckeditor/ckeditor5-link/src/linkimage';
 
 import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config';
+import PasteFromOffice from '@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice';
+import ListStyle from '@ckeditor/ckeditor5-list/src/liststyle';
 
 ClassicEditor
 	.create( document.querySelector( '#editor' ), {
@@ -46,7 +48,8 @@ ClassicEditor
 			Highlight, FontColor, FontBackgroundColor, FontFamily, FontSize,
 			IndentBlock, WordCount, EasyImage,
 			TodoList, PageBreak, HorizontalLine, Mention, RemoveFormat, TextTransformation,
-			ImageResize, LinkImage
+			ImageResize, LinkImage,
+			PasteFromOffice, ListStyle
 		],
 		toolbar: [
 			'heading',