Ver código fonte

Merge pull request #89 from ckeditor/i/5645+2095

Fix: Fixed various issues with oddly formatted space run spans.
Kacper Tomporowski 6 anos atrás
pai
commit
2799693fe5

+ 6 - 3
packages/ckeditor5-paste-from-office/src/filters/space.js

@@ -20,8 +20,8 @@ export function normalizeSpacing( htmlString ) {
 	// Run normalizeSafariSpaceSpans() two times to cover nested spans.
 	return normalizeSafariSpaceSpans( normalizeSafariSpaceSpans( htmlString ) )
 		// Remove all \r\n from "spacerun spans" so the last replace line doesn't strip all whitespaces.
-		.replace( /(<span style=['"]mso-spacerun:yes['"]>[\s]*?)[\r\n]+(\s*<\/span>)/g, '$1$2' )
-		.replace( /<span style=['"]mso-spacerun:yes['"]><\/span>/g, '' )
+		.replace( /(<span\s+style=['"]mso-spacerun:yes['"]>[\s]*?)[\r\n]+(\s*<\/span>)/g, '$1$2' )
+		.replace( /<span\s+style=['"]mso-spacerun:yes['"]><\/span>/g, '' )
 		.replace( / <\//g, '\u00A0</' )
 		.replace( / <o:p><\/o:p>/g, '\u00A0<o:p></o:p>' )
 		// Remove <o:p> block filler from empty paragraph. Safari uses \u00A0 instead of &nbsp;.
@@ -41,7 +41,10 @@ export function normalizeSpacerunSpans( htmlDocument ) {
 	htmlDocument.querySelectorAll( 'span[style*=spacerun]' ).forEach( el => {
 		// Use `el.childNodes[ 0 ].data.length` instead of `el.innerText.length`. For `el.innerText.length` which
 		// contains spaces mixed with `&nbsp;` Edge browser returns incorrect length.
-		const innerTextLength = el.childNodes[ 0 ].data.length;
+		const innerTextLength = ( el.childNodes &&
+			el.childNodes[ 0 ] &&
+			el.childNodes[ 0 ].data &&
+			el.childNodes[ 0 ].data.length ) || 0;
 
 		el.innerHTML = Array( innerTextLength + 1 ).join( '\u00A0 ' ).substr( 0, innerTextLength );
 	} );

+ 36 - 0
packages/ckeditor5-paste-from-office/tests/filters/space.js

@@ -81,6 +81,24 @@ describe( 'PasteFromOffice - filters', () => {
 
 				expect( normalizeSpacing( input ) ).to.equal( expected );
 			} );
+
+			// ckeditor5#2095
+			it( 'should detect space spans which are split into multiple lines', () => {
+				const input =
+					'<p><span style=\'font-size:13.0pt;line-height:150%;\n' +
+					'font-family:"Times New Roman",serif\'><span\n' +
+					'style=\'mso-spacerun:yes\'>\n' +
+					'</span><span style=\'mso-spacerun:yes\'>          </span><span\n' +
+					'style=\'mso-spacerun:yes\'>    </span><span style=\'mso-spacerun:yes\'> </span>Test<o:p></o:p></span></p>';
+
+				const expected =
+					'<p><span style=\'font-size:13.0pt;line-height:150%;\nfont-family:"Times New Roman",serif\'>' +
+					'<span style=\'mso-spacerun:yes\'>          </span>' +
+					'<span\nstyle=\'mso-spacerun:yes\'>    </span>' +
+					'<span style=\'mso-spacerun:yes\'> </span>Test<o:p></o:p></span></p>';
+
+				expect( normalizeSpacing( input ) ).to.equal( expected );
+			} );
 		} );
 
 		describe( 'normalizeSpacerunSpans()', () => {
@@ -100,6 +118,24 @@ describe( 'PasteFromOffice - filters', () => {
 
 				expect( htmlDocument.body.innerHTML.replace( /'/g, '"' ).replace( /: /g, ':' ) ).to.equal( expected );
 			} );
+
+			// ckeditor5#5645
+			it( 'should normalize spaces inside special "span.spacerun" elements that contain no data', () => {
+				const input = '<p> <span style=\'mso-spacerun:yes\'>   </span>Foo</p>' +
+					'<p> Baz <span style=\'mso-spacerun:yes\'></span></p>';
+
+				const expected = '<p> <span style="mso-spacerun:yes">&nbsp; &nbsp;</span>Foo</p>' +
+					'<p> Baz <span style="mso-spacerun:yes"></span></p>';
+
+				const domParser = new DOMParser();
+				const htmlDocument = domParser.parseFromString( input, 'text/html' );
+
+				expect( htmlDocument.body.innerHTML.replace( /'/g, '"' ).replace( /: /g, ':' ) ).to.not.equal( expected );
+
+				normalizeSpacerunSpans( htmlDocument );
+
+				expect( htmlDocument.body.innerHTML.replace( /'/g, '"' ).replace( /: /g, ':' ) ).to.equal( expected );
+			} );
 		} );
 	} );
 } );