8
0
Просмотр исходного кода

Pasting a plain text will inherit selection attributes.

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

+ 23 - 0
packages/ckeditor5-clipboard/src/clipboard.js

@@ -103,6 +103,15 @@ export default class Clipboard extends Plugin {
 					return;
 				}
 
+				// While pasting plain text, apply selection attributes on the text.
+				if ( isPlainText( modelFragment ) ) {
+					const child = modelFragment.getChild( 0 );
+
+					model.change( writer => {
+						writer.setAttributes( modelDocument.selection.getAttributes(), child );
+					} );
+				}
+
 				model.insertContent( modelFragment );
 				evt.stop();
 			}
@@ -198,3 +207,17 @@ export default class Clipboard extends Plugin {
  *
  * @member {'copy'|'cut'} module:clipboard/clipboard~ClipboardOutputEventData#method
  */
+
+// Returns true if specified `documentFragment` represents a plain text.
+//
+// @param {module:engine/view/documentfragment~DocumentFragment} documentFragment
+// @returns {Boolean}
+function isPlainText( documentFragment ) {
+	if ( documentFragment.childCount > 1 ) {
+		return false;
+	}
+
+	const child = documentFragment.getChild( 0 );
+
+	return [ ...child.getAttributeKeys() ].length == 0;
+}

+ 59 - 0
packages/ckeditor5-clipboard/tests/clipboard.js

@@ -343,6 +343,65 @@ describe( 'Clipboard feature', () => {
 			expect( spy.callCount ).to.equal( 1 );
 		} );
 
+		// https://github.com/ckeditor/ckeditor5/issues/1006
+		describe( 'pasting plain text', () => {
+			let model;
+
+			beforeEach( () => {
+				model = editor.model;
+
+				editor.model.schema.extend( '$text', { allowAttributes: 'bold' } );
+			} );
+
+			it( 'should inherit selection attributes (collapsed selection)', () => {
+				const insertContent = model.insertContent.bind( model );
+				let insertedNode;
+
+				sinon.stub( model, 'insertContent' ).callsFake( documentFragment => {
+					insertedNode = documentFragment.getChild( 0 );
+
+					return insertContent( documentFragment );
+				} );
+
+				setModelData( model, '<paragraph><$text bold="true">Bolded []text.</$text></paragraph>' );
+
+				const dataTransferMock = createDataTransfer( { 'text/plain': 'foo' } );
+
+				viewDocument.fire( 'paste', {
+					dataTransfer: dataTransferMock,
+					stopPropagation() {},
+					preventDefault() {}
+				} );
+
+				expect( getModelData( model ) ).to.equal( '<paragraph><$text bold="true">Bolded foo[]text.</$text></paragraph>' );
+				expect( insertedNode.getAttribute( 'bold' ) ).to.equal( true );
+			} );
+
+			it( 'should inherit selection attributes (non-collapsed selection)', () => {
+				const insertContent = model.insertContent.bind( model );
+				let insertedNode;
+
+				sinon.stub( model, 'insertContent' ).callsFake( documentFragment => {
+					insertedNode = documentFragment.getChild( 0 );
+
+					return insertContent( documentFragment );
+				} );
+
+				setModelData( model, '<paragraph><$text bold="true">Bolded [text.]</$text></paragraph>' );
+
+				const dataTransferMock = createDataTransfer( { 'text/plain': 'foo' } );
+
+				viewDocument.fire( 'paste', {
+					dataTransfer: dataTransferMock,
+					stopPropagation() {},
+					preventDefault() {}
+				} );
+
+				expect( getModelData( model ) ).to.equal( '<paragraph><$text bold="true">Bolded foo[]</$text></paragraph>' );
+				expect( insertedNode.getAttribute( 'bold' ) ).to.equal( true );
+			} );
+		} );
+
 		function createDataTransfer( data ) {
 			return {
 				getData( type ) {