Преглед на файлове

Move utils to plugin to provide better way of testing it.

Mateusz Samsel преди 6 години
родител
ревизия
bec8970345

+ 95 - 2
packages/ckeditor5-paste-from-office/src/pastefromoffice.js

@@ -9,7 +9,10 @@
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 
-import { _inputTransformationListener } from './utils';
+import { parseHtml } from './filters/parse';
+import { transformListItemLikeElementsIntoLists } from './filters/list';
+import { replaceImagesSourceWithBase64 } from './filters/image';
+import { removeBoldTagWrapper } from './filters/common';
 
 /**
  * The Paste from Office plugin.
@@ -38,8 +41,98 @@ export default class PasteFromOffice extends Plugin {
 		this.listenTo(
 			editor.plugins.get( 'Clipboard' ),
 			'inputTransformation',
-			_inputTransformationListener,
+			PasteFromOffice._inputTransformationListener,
 			{ priority: 'high' }
 		);
 	}
+
+	/**
+	 * Listener fired during {@link module:clipboard/clipboard~Clipboard#event:inputTransformation} event. Detects if content comes
+	 * from recognized source and normalize it.
+	 *
+	 * **Note**: this function was exposed mainly for testing purposes and should not be called directly.
+	 *
+	 * @private
+	 * @param {module:utils/eventinfo~EventInfo} evt
+	 * @param {Object} data passed with {@link module:clipboard/clipboard~Clipboard#event:inputTransformation}
+	 */
+	static _inputTransformationListener( evt, data ) {
+		const html = data.dataTransfer.getData( 'text/html' );
+
+		if ( data.pasteFromOfficeProcessed !== true ) {
+			switch ( PasteFromOffice._getInputType( html ) ) {
+				case 'msword':
+					data.content = PasteFromOffice._normalizeWordInput( html, data.dataTransfer );
+					break;
+				case 'gdocs':
+					data.content = PasteFromOffice._normalizeGoogleDocsInput( data.content );
+					break;
+				default:
+					break;
+			}
+
+			// Set the flag so if `inputTransformation` is re-fired, PFO will not process it again (#44).
+			data.pasteFromOfficeProcessed = true;
+		}
+	}
+
+	/**
+	 * Normalizes input pasted from Word to format suitable for editor {@link module:engine/model/model~Model}.
+	 *
+	 * **Note**: this function is exposed mainly for testing purposes and should not be called directly.
+	 *
+	 * @private
+	 * @param {String} input Word input.
+	 * @param {module:clipboard/datatransfer~DataTransfer} dataTransfer Data transfer instance.
+	 * @returns {module:engine/view/documentfragment~DocumentFragment} Normalized input.
+	 */
+	static _normalizeWordInput( input, dataTransfer ) {
+		const { body, stylesString } = parseHtml( input );
+
+		transformListItemLikeElementsIntoLists( body, stylesString );
+		replaceImagesSourceWithBase64( body, dataTransfer.getData( 'text/rtf' ) );
+
+		return body;
+	}
+
+	/**
+	 * Normalizes input pasted from Google Docs to format suitable for editor {@link module:engine/model/model~Model}.
+	 *
+	 * **Note**: this function is exposed mainly for testing purposes and should not be called directly.
+	 *
+	 * @private
+	 * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment normalized clipboard data
+	 * @returns {module:engine/view/documentfragment~DocumentFragment} document fragment normalized with set of filters dedicated
+	 * for Google Docs
+	 */
+	static _normalizeGoogleDocsInput( documentFragment ) {
+		return removeBoldTagWrapper( documentFragment );
+	}
+
+	/**
+	 * Determines if given paste data came from specific office-like application
+	 * Recognized are:
+	 * * 'msword' for Microsoft Words desktop app
+	 * * 'gdocs' for Google Docs online app
+	 *
+	 * @private
+	 * @param {String} html `text/html` string from data transfer
+	 * @return {String|null} type of app which is source of a data or null
+	 */
+	static _getInputType( html ) {
+		if ( html ) {
+			if (
+				/<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/i.test( html ) ||
+				/xmlns:o="urn:schemas-microsoft-com/i.test( html )
+			) {
+				// Microsoft Word detection
+				return 'msword';
+			} else if ( /id=("|')docs-internal-guid-[-0-9a-f]+("|')/.test( html ) ) {
+				// Google Docs detection
+				return 'gdocs';
+			}
+		}
+
+		return null;
+	}
 }

+ 0 - 100
packages/ckeditor5-paste-from-office/src/utils.js

@@ -1,100 +0,0 @@
-/**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/**
- * @module paste-from-office/pastefromoffice/utils
- */
-
-import { parseHtml } from './filters/parse';
-import { transformListItemLikeElementsIntoLists } from './filters/list';
-import { replaceImagesSourceWithBase64 } from './filters/image';
-import { removeBoldTagWrapper } from './filters/common';
-
-/**
- * Listener fired during {@link module:clipboard/clipboard~Clipboard#event:inputTransformation} event. Detects if content comes
- * from recognized source and normalize it.
- *
- * **Note**: this function was exposed mainly for testing purposes and should not be called directly.
- *
- * @param {module:utils/eventinfo~EventInfo} evt
- * @param {Object} data passed with {@link module:clipboard/clipboard~Clipboard#event:inputTransformation}
- */
-export function _inputTransformationListener( evt, data ) {
-	const html = data.dataTransfer.getData( 'text/html' );
-
-	if ( data.pasteFromOfficeProcessed !== true ) {
-		switch ( getInputType( html ) ) {
-			case 'msword':
-				data.content = _normalizeWordInput( html, data.dataTransfer );
-				break;
-			case 'gdocs':
-				data.content = _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;
-	}
-}
-
-/**
- * Normalizes input pasted from Word to format suitable for editor {@link module:engine/model/model~Model}.
- *
- * **Note**: this function is exposed mainly for testing purposes and should not be called directly.
- *
- * @private
- * @param {String} input Word input.
- * @param {module:clipboard/datatransfer~DataTransfer} dataTransfer Data transfer instance.
- * @returns {module:engine/view/documentfragment~DocumentFragment} Normalized input.
- */
-export function _normalizeWordInput( input, dataTransfer ) {
-	const { body, stylesString } = parseHtml( input );
-
-	transformListItemLikeElementsIntoLists( body, stylesString );
-	replaceImagesSourceWithBase64( body, dataTransfer.getData( 'text/rtf' ) );
-
-	return body;
-}
-
-/**
- * Normalizes input pasted from Google Docs to format suitable for editor {@link module:engine/model/model~Model}.
- *
- * **Note**: this function is exposed mainly for testing purposes and should not be called directly.
- *
- * @private
- * @param {module:engine/view/documentfragment~DocumentFragment} documentFragment normalized clipboard data
- * @returns {module:engine/view/documentfragment~DocumentFragment} document fragment normalized with set of filters dedicated
- * for Google Docs
- */
-export function _normalizeGDocsInput( documentFragment ) {
-	return removeBoldTagWrapper( documentFragment );
-}
-
-/** Determines if given paste data came from specific office-like application
- * Recognized are:
- * * 'msword' for Microsoft Words desktop app
- * * 'gdocs' for Google Docs online app
- *
- * @param {String} html `text/html` string from data transfer
- * @return {String|null} type of app which is source of a data or null
- */
-export function getInputType( html ) {
-	if ( html ) {
-		if (
-			/<meta\s*name="?generator"?\s*content="?microsoft\s*word\s*\d+"?\/?>/i.test( html ) ||
-			/xmlns:o="urn:schemas-microsoft-com/i.test( html )
-		) {
-			// Microsoft Word detection
-			return 'msword';
-		} else if ( /id=("|')docs-internal-guid-[-0-9a-f]+("|')/.test( html ) ) {
-			// Google Docs detection
-			return 'gdocs';
-		}
-	}
-
-	return null;
-}

+ 3 - 7
packages/ckeditor5-paste-from-office/tests/_utils/utils.js

@@ -8,9 +8,9 @@
 import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor';
 import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
 
+import PasteFromOffice from '../../src/pastefromoffice';
 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';
@@ -145,22 +145,18 @@ function generateNormalizationTests( title, fixtures, editorConfig, skip ) {
 	const htmlDataProcessor = new HtmlDataProcessor();
 
 	describe( title, () => {
-		let editor, pasteFromOfficePlugin;
+		let editor;
 
 		beforeEach( () => {
 			return VirtualTestEditor
 				.create( editorConfig )
 				.then( newEditor => {
 					editor = newEditor;
-
-					pasteFromOfficePlugin = editor.plugins.get( 'PasteFromOffice' );
 				} );
 		} );
 
 		afterEach( () => {
 			editor.destroy();
-
-			pasteFromOfficePlugin = null;
 		} );
 
 		for ( const name of Object.keys( fixtures.input ) ) {
@@ -174,7 +170,7 @@ function generateNormalizationTests( title, fixtures, editorConfig, skip ) {
 					} )
 				};
 
-				pasteFromOfficePlugin._inputTransformationListener( null, data );
+				PasteFromOffice._inputTransformationListener( null, data );
 
 				expectNormalized(
 					data.content,

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

@@ -16,74 +16,76 @@ describe( 'Paste from Office plugin', () => {
 
 	testUtils.createSinonSandbox();
 
-	before( () => {
-		content = new DocumentFragment();
-	} );
+	describe( '_normalizeWordInput()', () => {
+		before( () => {
+			content = new DocumentFragment();
+		} );
 
-	beforeEach( () => {
-		return VirtualTestEditor
-			.create( {
-				plugins: [ Clipboard, PasteFromOffice ]
-			} )
-			.then( newEditor => {
-				editor = newEditor;
-				normalizeSpy = testUtils.sinon.spy( editor.plugins.get( 'PasteFromOffice' ), '_normalizeWordInput' );
+		beforeEach( () => {
+			return VirtualTestEditor
+				.create( {
+					plugins: [ Clipboard, PasteFromOffice ]
+				} )
+				.then( newEditor => {
+					editor = newEditor;
+					normalizeSpy = testUtils.sinon.spy( PasteFromOffice, '_normalizeWordInput' );
+				} );
+		} );
+
+		it( 'runs normalizations if Word meta tag detected #1', () => {
+			const dataTransfer = createDataTransfer( {
+				'text/html': '<meta name=Generator content="Microsoft Word 15">'
 			} );
-	} );
 
-	it( 'runs normalizations if Word meta tag detected #1', () => {
-		const dataTransfer = createDataTransfer( {
-			'text/html': '<meta name=Generator content="Microsoft Word 15">'
+			editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
+
+			expect( normalizeSpy.calledOnce ).to.true;
 		} );
 
-		editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
+		it( 'runs normalizations if Word meta tag detected #2', () => {
+			const dataTransfer = createDataTransfer( {
+				'text/html': '<html><head><meta name="Generator"  content=Microsoft Word 15></head></html>'
+			} );
 
-		expect( normalizeSpy.calledOnce ).to.true;
-	} );
+			editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
 
-	it( 'runs normalizations if Word meta tag detected #2', () => {
-		const dataTransfer = createDataTransfer( {
-			'text/html': '<html><head><meta name="Generator"  content=Microsoft Word 15></head></html>'
+			expect( normalizeSpy.calledOnce ).to.true;
 		} );
 
-		editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
+		it( 'does not normalize the content without Word meta tag', () => {
+			const dataTransfer = createDataTransfer( {
+				'text/html': '<meta name=Generator content="Other">'
+			} );
 
-		expect( normalizeSpy.calledOnce ).to.true;
-	} );
+			editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
 
-	it( 'does not normalize the content without Word meta tag', () => {
-		const dataTransfer = createDataTransfer( {
-			'text/html': '<meta name=Generator content="Other">'
+			expect( normalizeSpy.called ).to.false;
 		} );
 
-		editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
+		it( 'does not process content many times for the same `inputTransformation` event', () => {
+			const clipboard = editor.plugins.get( 'Clipboard' );
 
-		expect( normalizeSpy.called ).to.false;
-	} );
+			const dataTransfer = createDataTransfer( {
+				'text/html': '<html><head><meta name="Generator"  content=Microsoft Word 15></head></html>'
+			} );
 
-	it( 'does not process content many times for the same `inputTransformation` event', () => {
-		const clipboard = editor.plugins.get( 'Clipboard' );
+			let eventRefired = false;
+			clipboard.on( 'inputTransformation', ( evt, data ) => {
+				if ( !eventRefired ) {
+					eventRefired = true;
 
-		const dataTransfer = createDataTransfer( {
-			'text/html': '<html><head><meta name="Generator"  content=Microsoft Word 15></head></html>'
-		} );
+					evt.stop();
 
-		let eventRefired = false;
-		clipboard.on( 'inputTransformation', ( evt, data ) => {
-			if ( !eventRefired ) {
-				eventRefired = true;
+					clipboard.fire( 'inputTransformation', data );
+				}
 
-				evt.stop();
+				expect( data.pasteFromOfficeProcessed ).to.true;
+				expect( normalizeSpy.calledOnce ).to.true;
+			}, { priority: 'low' } );
 
-				clipboard.fire( 'inputTransformation', data );
-			}
+			editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
 
-			expect( data.pasteFromOfficeProcessed ).to.true;
 			expect( normalizeSpy.calledOnce ).to.true;
-		}, { priority: 'low' } );
-
-		editor.plugins.get( 'Clipboard' ).fire( 'inputTransformation', { content, dataTransfer } );
-
-		expect( normalizeSpy.calledOnce ).to.true;
+		} );
 	} );
 } );