浏览代码

Add test for google docs, fix unit test creator to fully simulate clipboard event. Extend unit test with information about data source. Some small docs and test naming improvements.

Mateusz Samsel 6 年之前
父节点
当前提交
7013e9e59d

+ 31 - 24
packages/ckeditor5-paste-from-office/src/pastefromoffice.js

@@ -8,7 +8,6 @@
  */
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
-import DocumentFragment from '@ckeditor/ckeditor5-engine/src/view/documentfragment';
 
 import { parseHtml } from './filters/parse';
 import { transformListItemLikeElementsIntoLists } from './filters/list';
@@ -38,25 +37,32 @@ export default class PasteFromOffice extends Plugin {
 	init() {
 		const editor = this.editor;
 
-		this.listenTo( editor.plugins.get( 'Clipboard' ), 'inputTransformation', ( evt, data ) => {
-			const html = data.dataTransfer.getData( 'text/html' );
-
-			if ( data.pasteFromOfficeProcessed !== true ) {
-				switch ( getInputType( html ) ) {
-					case 'msword':
-						data.content = this._normalizeWordInput( html, data.dataTransfer );
-						break;
-					case 'gdocs':
-						data.content = this._normalizeGDocsInput( data.content );
-						break;
-					default:
-						break;
-				}
-
-				// Set the flag so if `inputTransformation` is re-fired, PFO will not process it again (#44).
-				data.pasteFromOfficeProcessed = true;
+		this.listenTo(
+			editor.plugins.get( 'Clipboard' ),
+			'inputTransformation',
+			this._inputTransformationListener.bind( this ),
+			{ priority: 'high' }
+		);
+	}
+
+	_inputTransformationListener( evt, data ) {
+		const html = data.dataTransfer.getData( 'text/html' );
+
+		if ( data.pasteFromOfficeProcessed !== true ) {
+			switch ( getInputType( html ) ) {
+				case 'msword':
+					data.content = this._normalizeWordInput( html, data.dataTransfer );
+					break;
+				case 'gdocs':
+					data.content = this._normalizeGDocsInput( data.content );
+					break;
+				default:
+					break;
 			}
-		}, { priority: 'high' } );
+
+			// Set the flag so if `inputTransformation` is re-fired, PFO will not process it again (#44).
+			data.pasteFromOfficeProcessed = true;
+		}
 	}
 
 	/**
@@ -85,12 +91,13 @@ export default class PasteFromOffice extends Plugin {
 }
 
 function removeBoldTagWrapper( documentFragment ) {
-	if ( documentFragment.childCount === 1 ) {
-		const firstChild = documentFragment.getChild( 0 );
+	const firstChild = documentFragment.getChild( 0 );
 
-		if ( firstChild.name === 'b' && firstChild.getStyle( 'font-weight' ) === 'normal' ) {
-			return new DocumentFragment( firstChild.getChildren() );
-		}
+	if ( firstChild.name === 'b' && firstChild.getStyle( 'font-weight' ) === 'normal' ) {
+		const children = firstChild.getChildren();
+
+		documentFragment._removeChildren( 0 );
+		documentFragment._insertChild( 0, children );
 	}
 
 	return documentFragment;

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

@@ -0,0 +1,24 @@
+/**
+ * @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 simpleText from './simple-text/input.html';
+
+import simpleTextNormalized from './simple-text/normalized.html';
+
+import simpleTextModel from './simple-text/model.html';
+
+export const fixtures = {
+	input: {
+		simpleText
+	},
+	normalized: {
+		simpleText: simpleTextNormalized
+	},
+	model: {
+		simpleText: simpleTextModel
+	}
+};
+
+export const browserFixtures = {};

文件差异内容过多而无法显示
+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/simple-text/input.html


+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/simple-text/model.html

@@ -0,0 +1 @@
+<paragraph>Hello world</paragraph>

+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/simple-text/normalized.html

@@ -0,0 +1 @@
+<p dir="ltr" style="line-height:1.38;margin-bottom:0pt;margin-top:0pt"><span style="background-color:transparent;color:#000000;font-family:Arial;font-size:11pt;font-style:normal;font-variant:normal;font-weight:400;text-decoration:none;vertical-align:baseline;white-space:pre-wrap">Hello world</span></p><br class="Apple-interchange-newline">

文件差异内容过多而无法显示
+ 1 - 0
packages/ckeditor5-paste-from-office/tests/_data/paste-from-google-docs/simple-text/simple-text.html


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

@@ -9,6 +9,7 @@ import { fixtures as image, browserFixtures as imageBrowser } from '../_data/ima
 import { fixtures as link, browserFixtures as linkBrowser } from '../_data/link/index.js';
 import { fixtures as list, browserFixtures as listBrowser } from '../_data/list/index.js';
 import { fixtures as spacing, browserFixtures as spacingBrowser } from '../_data/spacing/index.js';
+import { fixtures as simpleText, browserFixtures as simpleTextBrowser } from '../_data/paste-from-google-docs/index';
 
 // Generic fixtures.
 export const fixtures = {
@@ -16,7 +17,8 @@ export const fixtures = {
 	image,
 	link,
 	list,
-	spacing
+	spacing,
+	simpleText
 };
 
 // Browser specific fixtures.
@@ -25,5 +27,6 @@ export const browserFixtures = {
 	image: imageBrowser,
 	link: linkBrowser,
 	list: listBrowser,
-	spacing: spacingBrowser
+	spacing: spacingBrowser,
+	simpleTextBrowser
 };

+ 32 - 11
packages/ckeditor5-paste-from-office/tests/_utils/utils.js

@@ -8,6 +8,9 @@
 import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
 import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
 
+import HtmlDataProcessor from '@ckeditor/ckeditor5-engine/src/dataprocessor/htmldataprocessor';
+import normalizeClipboardData from '@ckeditor/ckeditor5-clipboard/src/utils/normalizeclipboarddata';
+
 import normalizeHtml from '@ckeditor/ckeditor5-utils/tests/_utils/normalizehtml';
 import { setData, stringify as stringifyModel } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { stringify as stringifyView } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
@@ -42,6 +45,7 @@ export function createDataTransfer( data ) {
  * @param {Object} config
  * @param {String} config.type Type of tests to generate, could be 'normalization' or 'integration'.
  * @param {String} config.input Name of the fixtures group. Usually stored in `/tests/_data/groupname/`.
+ * @param {String} config.dataSource Name of the office app, which was used to generate data.
  * @param {Array.<String>} config.browsers List of all browsers for which to generate tests.
  * @param {Object} [config.editorConfig] Editor config which is passed to editor `create()` method.
  * @param {Object} [config.skip] List of fixtures for any browser to skip. The supported format is:
@@ -55,6 +59,10 @@ export function generateTests( config ) {
 		throw new Error( `Invalid tests type - \`config.type\`: '${ config.type }'.` );
 	}
 
+	if ( !config.dataSource ) {
+		throw new Error( 'No `config.dataSource` option provided.' );
+	}
+
 	if ( !config.input ) {
 		throw new Error( 'No `config.input` option provided.' );
 	}
@@ -67,16 +75,18 @@ export function generateTests( config ) {
 	const generateSuiteFn = config.type === 'normalization' ? generateNormalizationTests : generateIntegrationTests;
 
 	describe( config.type, () => {
-		describe( config.input, () => {
-			const editorConfig = config.editorConfig || {};
+		describe( config.dataSource, () => {
+			describe( config.input, () => {
+				const editorConfig = config.editorConfig || {};
 
-			for ( const group of Object.keys( groups ) ) {
-				const skip = config.skip && config.skip[ group ] ? config.skip[ group ] : [];
+				for ( const group of Object.keys( groups ) ) {
+					const skip = config.skip && config.skip[ group ] ? config.skip[ group ] : [];
 
-				if ( groups[ group ] ) {
-					generateSuiteFn( group, groups[ group ], editorConfig, skip );
+					if ( groups[ group ] ) {
+						generateSuiteFn( group, groups[ group ], editorConfig, skip );
+					}
 				}
-			}
+			} );
 		} );
 	} );
 }
@@ -124,12 +134,16 @@ function groupFixturesByBrowsers( browsers, fixturesGroup, skipBrowsers ) {
 }
 
 // Generates normalization tests based on a provided fixtures. For each input fixture one test is generated.
+// Please notice that normalization compares generated Views, not DOM. That's why there might appear some not familiar structures,
+// like closing tags for void tags, for example `<br></br>`.
 //
 // @param {String} title Tests group title.
 // @param {Object} fixtures Object containing fixtures.
 // @param {Object} editorConfig Editor config with which test editor will be created.
 // @param {Array.<String>} skip Array of fixtures names which tests should be skipped.
 function generateNormalizationTests( title, fixtures, editorConfig, skip ) {
+	const htmlDataProcessor = new HtmlDataProcessor();
+
 	describe( title, () => {
 		let editor, pasteFromOfficePlugin;
 
@@ -151,12 +165,19 @@ function generateNormalizationTests( title, fixtures, editorConfig, skip ) {
 
 		for ( const name of Object.keys( fixtures.input ) ) {
 			( skip.indexOf( name ) !== -1 ? it.skip : it )( name, () => {
-				const dataTransfer = createDataTransfer( {
-					'text/rtf': fixtures.inputRtf && fixtures.inputRtf[ name ]
-				} );
+				// Simulate data from Clipboard event
+				const data = {
+					content: htmlDataProcessor.toView( normalizeClipboardData( fixtures.input[ name ] ) ),
+					dataTransfer: createDataTransfer( {
+						'text/html': fixtures.input[ name ],
+						'text/rtf': fixtures.inputRtf && fixtures.inputRtf[ name ]
+					} )
+				};
+
+				pasteFromOfficePlugin._inputTransformationListener( null, data );
 
 				expectNormalized(
-					pasteFromOfficePlugin._normalizeWordInput( fixtures.input[ name ], dataTransfer ),
+					data.content,
 					fixtures.normalized[ name ]
 				);
 			} );

+ 16 - 1
packages/ckeditor5-paste-from-office/tests/data/integration.js

@@ -22,10 +22,11 @@ import { generateTests } from '../_utils/utils';
 
 const browsers = [ 'chrome', 'firefox', 'safari', 'edge' ];
 
-describe( 'Paste from Office', () => {
+describe( 'Paste from Office - automatic', () => {
 	generateTests( {
 		input: 'basic-styles',
 		type: 'integration',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig: {
 			plugins: [ Clipboard, Paragraph, Heading, Bold, Italic, Underline, Strikethrough, PasteFromOffice ]
@@ -38,6 +39,7 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'image',
 		type: 'integration',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig: {
 			plugins: [ Clipboard, Paragraph, Image, Table, PasteFromOffice ]
@@ -53,6 +55,7 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'link',
 		type: 'integration',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig: {
 			plugins: [ Clipboard, Paragraph, Heading, Bold, Link, ShiftEnter, PasteFromOffice ]
@@ -65,6 +68,7 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'list',
 		type: 'integration',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig: {
 			plugins: [ Clipboard, Paragraph, Heading, Bold, Italic, Underline, Link, List, PasteFromOffice ]
@@ -77,9 +81,20 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'spacing',
 		type: 'integration',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig: {
 			plugins: [ Clipboard, Paragraph, Bold, Italic, Underline, PasteFromOffice ]
 		}
 	} );
+
+	generateTests( {
+		input: 'simpleText',
+		type: 'integration',
+		dataSource: 'Google Docs',
+		browsers,
+		editorConfig: {
+			plugins: [ Clipboard, Paragraph, Bold, PasteFromOffice ]
+		}
+	} );
 } );

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

@@ -14,10 +14,11 @@ const editorConfig = {
 	plugins: [ Clipboard, PasteFromOffice ]
 };
 
-describe( 'Paste from Office', () => {
+describe( 'Paste from Office - automatic', () => {
 	generateTests( {
 		input: 'basic-styles',
 		type: 'normalization',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig
 	} );
@@ -25,6 +26,7 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'image',
 		type: 'normalization',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig
 	} );
@@ -32,6 +34,7 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'link',
 		type: 'normalization',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig
 	} );
@@ -39,6 +42,7 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'list',
 		type: 'normalization',
+		dataSource: 'MS Word',
 		browsers,
 		editorConfig
 	} );
@@ -46,6 +50,15 @@ describe( 'Paste from Office', () => {
 	generateTests( {
 		input: 'spacing',
 		type: 'normalization',
+		dataSource: 'MS Word',
+		browsers,
+		editorConfig
+	} );
+
+	generateTests( {
+		input: 'simpleText',
+		type: 'normalization',
+		dataSource: 'Google Docs',
 		browsers,
 		editorConfig
 	} );

+ 8 - 3
packages/ckeditor5-paste-from-office/tests/manual/integration.html

@@ -1,3 +1,8 @@
+<style>
+.clipboard-title {
+	font-size: 1em;
+}
+</style>
 <div id="editor">
 	<h2>Paste here:</h2>
 
@@ -10,11 +15,11 @@
 	</ul>
 </div>
 
-Clipboard HTML
+<h2 class="clipboard-title">Clipboard HTML</h2>
 <div id="html" contenteditable="true" style="width:100%;height:300px;background-color:#EEE;overflow:auto;"></div>
 
-Clipboard text
+<h2 class="clipboard-title">Clipboard text</h2>
 <div id="text" contenteditable="true" style="width:100%;height:100px;background-color:#DDD;overflow:auto;"></div>
 
-Clipboard HTML after transformation
+<h2 class="clipboard-title">Clipboard normalized HTML view after transformation</h2>
 <div id="data" contenteditable="true" style="width:100%;height:100px;background-color:#CCC;overflow:auto;"></div>