Parcourir la source

Improved tests for auto-embeding.

Kamil Piechaczek il y a 7 ans
Parent
commit
fa8fe2f2f6

+ 2 - 0
packages/ckeditor5-media-embed/package.json

@@ -21,7 +21,9 @@
     "@ckeditor/ckeditor5-basic-styles": "^10.0.2",
     "@ckeditor/ckeditor5-editor-classic": "^11.0.0",
     "@ckeditor/ckeditor5-link": "^10.0.3",
+    "@ckeditor/ckeditor5-list": "^11.0.1",
     "@ckeditor/ckeditor5-paragraph": "^10.0.2",
+    "@ckeditor/ckeditor5-undo": "^10.0.2",
     "eslint": "^4.15.0",
     "eslint-config-ckeditor5": "^1.0.7",
     "husky": "^0.14.3",

+ 18 - 21
packages/ckeditor5-media-embed/src/mediaembed.js

@@ -59,9 +59,8 @@ export default class MediaEmbed extends Plugin {
 	 */
 	_attachAutoEmbedingEvents() {
 		const editor = this.editor;
-		const view = editor.editing.view;
 		const modelDocument = editor.model.document;
-		const mediaRegistry = editor.plugins.get( MediaEmbedEditing ).mediaRegistry;
+		const mediaRegistry = editor.plugins.get( MediaEmbedEditing ).registry;
 
 		let leftLivePosition, rightLivePosition;
 
@@ -77,28 +76,19 @@ export default class MediaEmbed extends Plugin {
 			rightLivePosition.stickiness = 'toNext';
 		} );
 
-		// Detach the live positions after pasting the content.
-		this.listenTo( editor.plugins.get( Clipboard ), 'inputTransformation', () => {
-			leftLivePosition.detach();
-			rightLivePosition.detach();
-
-			leftLivePosition = null;
-			rightLivePosition = null;
-		}, { priority: 'lowest' } );
-
 		modelDocument.on( 'change:data', () => {
 			if ( !leftLivePosition ) {
 				return;
 			}
 
 			const urlRange = new Range( leftLivePosition, rightLivePosition );
-			const walker = new TreeWalker( { boundaries: urlRange } );
+			const walker = new TreeWalker( { boundaries: urlRange, ignoreElementEnd: true } );
 
 			let url = '';
 
 			for ( const node of walker ) {
-				if ( !node.type === 'text' ) {
-					return;
+				if ( node.type === 'elementStart' ) {
+					return detach();
 				}
 
 				url += node.item.data;
@@ -106,12 +96,12 @@ export default class MediaEmbed extends Plugin {
 
 			// If the url does not match to universal url regexp, let's skip that.
 			if ( !url.match( URL_REGEXP ) ) {
-				return;
+				return detach();
 			}
 
 			// If the url is valid from MediaEmbed plugin point of view, let's use it.
 			if ( !mediaRegistry.hasMedia( url ) ) {
-				return;
+				return detach();
 			}
 
 			// `leftLivePosition` won't be available in `setTimeout` function so let's clone it.
@@ -119,16 +109,23 @@ export default class MediaEmbed extends Plugin {
 
 			global.window.setTimeout( () => {
 				editor.model.change( writer => {
-					const mediaElement = writer.createElement( 'media', { url } );
+					// const mediaElement = writer.createElement( 'media', { url } );
 
 					writer.remove( urlRange );
-					writer.insert( mediaElement, positionToInsert );
-					writer.setSelection( mediaElement, 'on' );
-
-					view.scrollToTheSelection();
+					// writer.insert( mediaElement, positionToInsert );
+					writer.setSelection( positionToInsert );
+					editor.commands.execute( 'mediaEmbed', url );
 				} );
 			}, 500 );
 		} );
+
+		function detach() {
+			leftLivePosition.detach();
+			rightLivePosition.detach();
+
+			leftLivePosition = null;
+			rightLivePosition = null;
+		}
 	}
 }
 

+ 130 - 16
packages/ckeditor5-media-embed/tests/mediaembed.js

@@ -11,7 +11,9 @@ import Widget from '@ckeditor/ckeditor5-widget/src/widget';
 import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Link from '@ckeditor/ckeditor5-link/src/link';
+import List from '@ckeditor/ckeditor5-list/src/list';
 import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Undo from '@ckeditor/ckeditor5-undo/src/undo';
 import global from '@ckeditor/ckeditor5-utils/src/dom/global';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
@@ -24,7 +26,7 @@ describe( 'MediaEmbed', () => {
 
 		return ClassicTestEditor
 			.create( editorElement, {
-				plugins: [ MediaEmbed, Paragraph, Link, Bold ]
+				plugins: [ MediaEmbed, Paragraph, Link, Bold, Undo, List ]
 			} )
 			.then( newEditor => {
 				editor = newEditor;
@@ -62,10 +64,54 @@ describe( 'MediaEmbed', () => {
 	} );
 
 	describe( 'auto-media embed', () => {
+		let clock;
+
+		beforeEach( () => {
+			clock = sinon.useFakeTimers();
+		} );
+
+		afterEach( () => {
+			clock.restore();
+		} );
+
+		it( 'replaces pasted text with media element after 500ms', () => {
+			setData( editor.model, '<paragraph>[]</paragraph>' );
+			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph>https://www.youtube.com/watch?v=H08tGjXNHO4[]</paragraph>'
+			);
+
+			clock.tick( 500 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph></paragraph>[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
+			);
+		} );
+
+		it( 'can undo auto-embeding', () => {
+			setData( editor.model, '<paragraph>[]</paragraph>' );
+			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph>https://www.youtube.com/watch?v=H08tGjXNHO4[]</paragraph>'
+			);
+
+			clock.tick( 500 );
+
+			editor.commands.execute( 'undo' );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph>https://www.youtube.com/watch?v=H08tGjXNHO4[]</paragraph>'
+			);
+		} );
+
 		it( 'works for a full URL (https + "www" sub-domain)', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph></paragraph>[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
 			);
@@ -75,6 +121,8 @@ describe( 'MediaEmbed', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'https://youtube.com/watch?v=H08tGjXNHO4' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph></paragraph>[<media url="https://youtube.com/watch?v=H08tGjXNHO4"></media>]'
 			);
@@ -84,6 +132,8 @@ describe( 'MediaEmbed', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'http://www.youtube.com/watch?v=H08tGjXNHO4' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph></paragraph>[<media url="http://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
 			);
@@ -93,6 +143,8 @@ describe( 'MediaEmbed', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'http://youtube.com/watch?v=H08tGjXNHO4' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph></paragraph>[<media url="http://youtube.com/watch?v=H08tGjXNHO4"></media>]'
 			);
@@ -102,6 +154,8 @@ describe( 'MediaEmbed', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'www.youtube.com/watch?v=H08tGjXNHO4' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph></paragraph>[<media url="www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
 			);
@@ -111,6 +165,8 @@ describe( 'MediaEmbed', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'youtube.com/watch?v=H08tGjXNHO4' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph></paragraph>[<media url="youtube.com/watch?v=H08tGjXNHO4"></media>]'
 			);
@@ -120,15 +176,63 @@ describe( 'MediaEmbed', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'https://twitter.com/ckeditor/status/1035181110140063749' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph></paragraph>[<media url="https://twitter.com/ckeditor/status/1035181110140063749"></media>]'
 			);
 		} );
 
+		it( 'works for URL that was pasted as a link', () => {
+			setData( editor.model, '<paragraph>[]</paragraph>' );
+			pasteHtml( editor, '<a href="https://www.youtube.com/watch?v=H08tGjXNHO4">https://www.youtube.com/watch?v=H08tGjXNHO4</a>' );
+
+			clock.tick( 500 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph></paragraph>[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
+			);
+		} );
+
+		it( 'works for URL that contains some inline styles', () => {
+			setData( editor.model, '<paragraph>[]</paragraph>' );
+			pasteHtml( editor, '<b>https://www.youtube.com/watch?v=H08tGjXNHO4</b>' );
+
+			clock.tick( 500 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph></paragraph>[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
+			);
+		} );
+
+		it( 'works for not collapsed selection inside single element', () => {
+			setData( editor.model, '<paragraph>[Foo]</paragraph>' );
+			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
+
+			clock.tick( 500 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph></paragraph>[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
+			);
+		} );
+
+		it( 'works for not collapsed selection over a few elements', () => {
+			setData( editor.model, '<paragraph>Fo[o</paragraph><paragraph>Ba]r</paragraph>' );
+			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
+
+			clock.tick( 500 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<paragraph>For</paragraph>[<media url="https://www.youtube.com/watch?v=H08tGjXNHO4"></media>]'
+			);
+		} );
+
 		it( 'does nothing if a URL is invalid', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'https://youtube.com' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph>https://youtube.com[]</paragraph>'
 			);
@@ -138,30 +242,21 @@ describe( 'MediaEmbed', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4 https://www.youtube.com/watch?v=H08tGjXNHO4' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph>https://www.youtube.com/watch?v=H08tGjXNHO4 https://www.youtube.com/watch?v=H08tGjXNHO4[]</paragraph>'
 			);
 		} );
 
-		it( 'does nothing if pasted link', () => {
+		it( 'does nothing if pasted text contains a valid URL', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
-			pasteHtml( editor, '<a href="https://www.youtube.com/watch?v=H08tGjXNHO4">https://www.youtube.com/watch?v=H08tGjXNHO4</a>' );
+			pasteHtml( editor, 'Foo bar https://www.youtube.com/watch?v=H08tGjXNHO4 bar foo.' );
 
-			expect( getData( editor.model ) ).to.equal(
-				'<paragraph>' +
-					'<$text linkHref="https://www.youtube.com/watch?v=H08tGjXNHO4">https://www.youtube.com/watch?v=H08tGjXNHO4[]</$text>' +
-				'</paragraph>'
-			);
-		} );
-
-		it( 'does nothing if node contains a valid URL but it is not a text', () => {
-			setData( editor.model, '<paragraph>[]</paragraph>' );
-			pasteHtml( editor, '<b>https://www.youtube.com/watch?v=H08tGjXNHO4</b>' );
+			clock.tick( 500 );
 
 			expect( getData( editor.model ) ).to.equal(
-				'<paragraph>' +
-					'<$text bold="true">https://www.youtube.com/watch?v=H08tGjXNHO4[]</$text>' +
-				'</paragraph>'
+				'<paragraph>Foo bar https://www.youtube.com/watch?v=H08tGjXNHO4 bar foo.[]</paragraph>'
 			);
 		} );
 
@@ -172,6 +267,8 @@ describe( 'MediaEmbed', () => {
 				'<a href="https://www.youtube.com/watch?v=H08tGjXNHO4">https://www.youtube.com/watch?v=H08tGjXNHO4</a>'
 			);
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph>https://www.youtube.com/watch?v=H08tGjXNHO4 ' +
 					'<$text linkHref="https://www.youtube.com/watch?v=H08tGjXNHO4">https://www.youtube.com/watch?v=H08tGjXNHO4[]</$text>' +
@@ -179,10 +276,25 @@ describe( 'MediaEmbed', () => {
 			);
 		} );
 
+		it( 'does nothing if pastes a block of content that looks like a URL', () => {
+			setData( editor.model, '<paragraph>[]</paragraph>' );
+			pasteHtml( editor, '<ul><li>https://</li><li>youtube.com/watch?</li></ul><p>v=H08tGjXNHO4</p>' );
+
+			clock.tick( 500 );
+
+			expect( getData( editor.model ) ).to.equal(
+				'<listItem listIndent="0" listType="bulleted">https://</listItem>' +
+				'<listItem listIndent="0" listType="bulleted">youtube.com/watch?</listItem>' +
+				'<paragraph>v=H08tGjXNHO4[]</paragraph>'
+			);
+		} );
+
 		it( 'does nothing if a URL is invalid (space inside URL)', () => {
 			setData( editor.model, '<paragraph>[]</paragraph>' );
 			pasteHtml( editor, 'youtube.com/watch?v=H08tGjXNHO4&amp;param=foo bar' );
 
+			clock.tick( 500 );
+
 			expect( getData( editor.model ) ).to.equal(
 				'<paragraph>youtube.com/watch?v=H08tGjXNHO4&param=foo bar[]</paragraph>'
 			);
@@ -202,6 +314,8 @@ describe( 'MediaEmbed', () => {
 					setData( editor.model, '<paragraph>[]</paragraph>' );
 					pasteHtml( editor, 'https://www.youtube.com/watch?v=H08tGjXNHO4' );
 
+					clock.tick( 500 );
+
 					expect( getData( editor.model ) ).to.equal(
 						'<paragraph>https://www.youtube.com/watch?v=H08tGjXNHO4[]</paragraph>'
 					);