Kaynağa Gözat

Merge branch 'master' into i/6091

Maciej Gołaszewski 6 yıl önce
ebeveyn
işleme
5c3082b571

+ 105 - 0
packages/ckeditor5-clipboard/docs/framework/guides/deep-dive/clipboard.md

@@ -93,6 +93,111 @@ editor.plugins.get( 'Clipboard' ).on( 'inputTransformation', ( evt, data ) => {
 }, { priority: 'lowest' } );
 }, { priority: 'lowest' } );
 ```
 ```
 
 
+### Paste as plain text plugin example
+
+You can use knowledge from previous sections to create a full plugin which will allow users to paste the content as plain text while the feature is toggled on.
+
+If you are not familiar with creating plugins in CKEditor 5, we would advise starting from reading {@link framework/guides/creating-simple-plugin Creating a simple plugin} guide to get a better understanding of what's going on in the code below.
+
+```js
+import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
+
+import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
+import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
+
+import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
+import Command from '@ckeditor/ckeditor5-core/src/command';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+
+import plainTextToHtml from '@ckeditor/ckeditor5-clipboard/src/utils/plaintexttohtml';
+
+class PastePlainText extends Plugin {
+	static get pluginName() {
+		return 'PastePlainText'
+	}
+
+	static get requires() {
+		return [ PastePlainTextUI, PastePlainTextCommand ]
+	}
+
+	init() {
+		const editor = this.editor;
+
+		editor.commands.add( 'pastePlainText', new PastePlainTextCommand( editor ) );
+
+		// Logic responsible for converting HTML to plain text.
+		const clipboardPlugin = editor.plugins.get( 'Clipboard' );
+		const command = editor.commands.get( 'pastePlainText' );
+		const editingView = editor.editing.view;
+
+		editingView.document.on( 'clipboardInput', ( evt, data ) => {
+			if ( editor.isReadOnly || !command.value ) {
+				return;
+			}
+
+			const dataTransfer = data.dataTransfer;
+			let content = plainTextToHtml( dataTransfer.getData( 'text/plain' ) );
+			content = clipboardPlugin._htmlDataProcessor.toView( content );
+			clipboardPlugin.fire( 'inputTransformation', { content, dataTransfer } );
+			editingView.scrollToTheSelection();
+
+			evt.stop();
+		} );
+	}
+};
+
+class PastePlainTextUI extends Plugin {
+	init() {
+		const editor = this.editor;
+
+		editor.ui.componentFactory.add( 'pastePlainText', locale => {
+			const view = new ButtonView( locale );
+			const command = editor.commands.get( 'pastePlainText' );
+
+			view.set( {
+				label: 'Paste as plain text',
+				withText: true,
+				tooltip: true,
+				isToggleable: true
+			} );
+
+			// Callback executed once the button is clicked.
+			view.on( 'execute', () => {
+				editor.execute( 'pastePlainText' );
+			} );
+
+			view.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );
+
+			return view;
+		} );
+	}
+};
+
+class PastePlainTextCommand extends Command {
+	refresh() {
+		// Disable the command if the editor is in read-only mode.
+		this.isEnabled = !this.editor.isReadOnly;
+	}
+
+	execute() {
+		// Activate pasting plain text.
+		this.value = !this.value;
+	}
+}
+
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Essentials, Paragraph, Bold, Italic, PastePlainText ],
+		toolbar: [ 'bold', 'italic', 'pastePlainText' ],
+		// ...
+	} )
+	.catch( error => {
+    	console.log( error );
+	} );
+```
+
 ## Output pipeline
 ## Output pipeline
 
 
 The output pipeline is the equivalent of the input pipeline but for the copy and cut operations.
 The output pipeline is the equivalent of the input pipeline but for the copy and cut operations.

+ 6 - 6
packages/ckeditor5-clipboard/tests/utils/viewtoplaintext.js

@@ -8,7 +8,7 @@ import viewToPlainText from '../../src/utils/viewtoplaintext';
 import { parse as parseView } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
 import { parse as parseView } from '@ckeditor/ckeditor5-engine/src/dev-utils/view';
 
 
 describe( 'viewToPlainText()', () => {
 describe( 'viewToPlainText()', () => {
-	function test( viewString, expectedText ) {
+	function testViewToPlainText( viewString, expectedText ) {
 		const view = parseView( viewString );
 		const view = parseView( viewString );
 		const text = viewToPlainText( view );
 		const text = viewToPlainText( view );
 
 
@@ -16,14 +16,14 @@ describe( 'viewToPlainText()', () => {
 	}
 	}
 
 
 	it( 'should output text contents of given view', () => {
 	it( 'should output text contents of given view', () => {
-		test(
+		testViewToPlainText(
 			'<container:p>Foo<strong>Bar</strong>Xyz</container:p>',
 			'<container:p>Foo<strong>Bar</strong>Xyz</container:p>',
 			'FooBarXyz'
 			'FooBarXyz'
 		);
 		);
 	} );
 	} );
 
 
 	it( 'should put empty line between container elements', () => {
 	it( 'should put empty line between container elements', () => {
-		test(
+		testViewToPlainText(
 			'<container:h1>Header</container:h1>' +
 			'<container:h1>Header</container:h1>' +
 			'<container:p>Foo</container:p>' +
 			'<container:p>Foo</container:p>' +
 			'<container:p>Bar</container:p>' +
 			'<container:p>Bar</container:p>' +
@@ -35,7 +35,7 @@ describe( 'viewToPlainText()', () => {
 	} );
 	} );
 
 
 	it( 'should output alt attribute of image elements', () => {
 	it( 'should output alt attribute of image elements', () => {
-		test(
+		testViewToPlainText(
 			'<container:p>Foo</container:p>' +
 			'<container:p>Foo</container:p>' +
 			'<img src="foo.jpg" alt="Alt" />',
 			'<img src="foo.jpg" alt="Alt" />',
 
 
@@ -44,7 +44,7 @@ describe( 'viewToPlainText()', () => {
 	} );
 	} );
 
 
 	it( 'should not put empty line after li (if not needed)', () => {
 	it( 'should not put empty line after li (if not needed)', () => {
-		test(
+		testViewToPlainText(
 			'<container:p>Foo</container:p>' +
 			'<container:p>Foo</container:p>' +
 			'<container:ul>' +
 			'<container:ul>' +
 				'<container:li>A</container:li>' +
 				'<container:li>A</container:li>' +
@@ -58,7 +58,7 @@ describe( 'viewToPlainText()', () => {
 	} );
 	} );
 
 
 	it( 'should not put empty line before/after figcaption (if not needed)', () => {
 	it( 'should not put empty line before/after figcaption (if not needed)', () => {
-		test(
+		testViewToPlainText(
 			'<container:p>Foo</container:p>' +
 			'<container:p>Foo</container:p>' +
 			'<container:figure>' +
 			'<container:figure>' +
 				'<img src="foo.jpg" alt="Alt" />' +
 				'<img src="foo.jpg" alt="Alt" />' +