Преглед изворни кода

Execute auto link on enter and shiftEnter commands.

Maciej Gołaszewski пре 5 година
родитељ
комит
df44897aee
2 измењених фајлова са 98 додато и 13 уклоњено
  1. 56 11
      packages/ckeditor5-link/src/autolink.js
  2. 42 2
      packages/ckeditor5-link/tests/autolink.js

+ 56 - 11
packages/ckeditor5-link/src/autolink.js

@@ -9,8 +9,10 @@
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import TextWatcher from '@ckeditor/ckeditor5-typing/src/textwatcher';
+import getLastTextLine from '@ckeditor/ckeditor5-typing/src/utils/getlasttextline';
 
 const regexp = /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)) $/;
+const regExpII = /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*))$/;
 
 /**
  * The auto link plugin.
@@ -51,18 +53,61 @@ export default class AutoLink extends Plugin {
 				return;
 			}
 
-			const url = match[ 1 ];
+			applyAutoLink( match[ 1 ], range, editor );
+		} );
+	}
 
-			// Enqueue change to make undo step.
-			editor.model.enqueueChange( writer => {
-				const linkRange = writer.createRange(
-					range.end.getShiftedBy( -( 1 + url.length ) ),
-					range.end.getShiftedBy( -1 )
-				);
+	/**
+	 * @inheritDoc
+	 */
+	afterInit() {
+		const editor = this.editor;
 
-				// TODO: use command for decorators support.
-				writer.setAttribute( 'linkHref', url, linkRange );
-			} );
-		} );
+		const enterCommand = editor.commands.get( 'enter' );
+		const shiftEnterCommand = editor.commands.get( 'shiftEnter' );
+
+		shiftEnterCommand.on( 'execute', () => {
+			const position = editor.model.document.selection.getFirstPosition();
+
+			const rangeToCheck = editor.model.createRange(
+				editor.model.createPositionAt( position.parent, 0 ),
+				position.getShiftedBy( -1 )
+			);
+
+			checkAndApplyAutoLinkOnRange( rangeToCheck, editor );
+		}, { priority: 'low' } );
+
+		enterCommand.on( 'execute', () => {
+			const position = editor.model.document.selection.getFirstPosition();
+
+			const rangeToCheck = editor.model.createRange(
+				editor.model.createPositionAt( position.parent.previousSibling, 0 ),
+				editor.model.createPositionAt( position.parent.previousSibling, 'end' )
+			);
+
+			checkAndApplyAutoLinkOnRange( rangeToCheck, editor );
+		}, { priority: 'low' } );
+	}
+}
+
+function applyAutoLink( linkHref, range, editor, additionalOffset = 1 ) {
+	// Enqueue change to make undo step.
+	editor.model.enqueueChange( writer => {
+		const linkRange = writer.createRange(
+			range.end.getShiftedBy( -( additionalOffset + linkHref.length ) ),
+			range.end.getShiftedBy( -additionalOffset )
+		);
+
+		writer.setAttribute( 'linkHref', linkHref, linkRange );
+	} );
+}
+
+function checkAndApplyAutoLinkOnRange( rangeToCheck, editor ) {
+	const { text, range } = getLastTextLine( rangeToCheck, editor.model );
+
+	const match = regExpII.exec( text );
+
+	if ( match ) {
+		applyAutoLink( match[ 1 ], range, editor, 0 );
 	}
 }

+ 42 - 2
packages/ckeditor5-link/tests/autolink.js

@@ -4,13 +4,15 @@
  */
 
 import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
+import Enter from '@ckeditor/ckeditor5-enter/src/enter';
 import Input from '@ckeditor/ckeditor5-typing/src/input';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import ShiftEnter from '@ckeditor/ckeditor5-enter/src/shiftenter';
+import UndoEditing from '@ckeditor/ckeditor5-undo/src/undoediting';
 import { getData, setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 import LinkEditing from '../src/linkediting';
 import AutoLink from '../src/autolink';
-import UndoEditing from '@ckeditor/ckeditor5-undo/src/undoediting';
 
 describe( 'AutoLink', () => {
 	it( 'should be named', () => {
@@ -21,7 +23,9 @@ describe( 'AutoLink', () => {
 		let editor, model;
 
 		beforeEach( async () => {
-			editor = await ModelTestEditor.create( { plugins: [ Paragraph, Input, LinkEditing, AutoLink, UndoEditing ] } );
+			editor = await ModelTestEditor.create( {
+				plugins: [ Paragraph, Input, LinkEditing, AutoLink, UndoEditing, Enter, ShiftEnter ]
+			} );
 
 			model = editor.model;
 
@@ -54,6 +58,42 @@ describe( 'AutoLink', () => {
 			);
 		} );
 
+		it( 'adds linkHref attribute to a text link after a soft break', () => {
+			setData( model, '<paragraph>https://www.cksource.com[]</paragraph>' );
+
+			editor.execute( 'shiftEnter' );
+
+			expect( getData( model ) ).to.equal(
+				'<paragraph>' +
+					'<$text linkHref="https://www.cksource.com">https://www.cksource.com</$text>' +
+					'<softBreak></softBreak>[]' +
+				'</paragraph>'
+			);
+		} );
+
+		it( 'does not add linkHref attribute to a text link after double soft break', () => {
+			setData( model, '<paragraph>https://www.cksource.com<softBreak></softBreak>[]</paragraph>' );
+
+			editor.execute( 'shiftEnter' );
+
+			expect( getData( model ) ).to.equal(
+				'<paragraph>https://www.cksource.com<softBreak></softBreak><softBreak></softBreak>[]</paragraph>'
+			);
+		} );
+
+		it( 'adds linkHref attribute to a text link on enter', () => {
+			setData( model, '<paragraph>https://www.cksource.com[]</paragraph>' );
+
+			editor.execute( 'enter' );
+
+			expect( getData( model ) ).to.equal(
+				'<paragraph>' +
+					'<$text linkHref="https://www.cksource.com">https://www.cksource.com</$text>' +
+				'</paragraph>' +
+				'<paragraph>[]</paragraph>'
+			);
+		} );
+
 		it( 'can undo auto-linking', () => {
 			simulateTyping( 'https://www.cksource.com ' );