diff --git a/packages/ckeditor5-link/src/autolink.ts b/packages/ckeditor5-link/src/autolink.ts
index 437d20c4167..f25d11b97c2 100644
--- a/packages/ckeditor5-link/src/autolink.ts
+++ b/packages/ckeditor5-link/src/autolink.ts
@@ -201,27 +201,40 @@ export default class AutoLink extends Plugin {
const editor = this.editor;
const watcher = new TextWatcher( editor.model, text => {
+ let mappedText = text;
+
// 1. Detect Space after a text with a potential link.
- if ( !isSingleSpaceAtTheEnd( text ) ) {
+ if ( !isSingleSpaceAtTheEnd( mappedText ) ) {
return;
}
- // 2. Check text before last typed Space.
- const url = getUrlAtTextEnd( text.substr( 0, text.length - 1 ) );
+ // 2. Remove the last space character.
+ mappedText = mappedText.slice( 0, -1 );
+
+ // 3. Remove punctuation at the end of the URL if it exists.
+ if ( '!.:,;?'.includes( mappedText[ mappedText.length - 1 ] ) ) {
+ mappedText = mappedText.slice( 0, -1 );
+ }
+
+ // 4. Check text before last typed Space or punctuation.
+ const url = getUrlAtTextEnd( mappedText );
if ( url ) {
- return { url };
+ return {
+ url,
+ removedTrailingCharacters: text.length - mappedText.length
+ };
}
} );
- watcher.on>( 'matched:data', ( evt, data ) => {
- const { batch, range, url } = data;
+ watcher.on>( 'matched:data', ( evt, data ) => {
+ const { batch, range, url, removedTrailingCharacters } = data;
if ( !batch.isTyping ) {
return;
}
- const linkEnd = range.end.getShiftedBy( -1 ); // Executed after a space character.
+ const linkEnd = range.end.getShiftedBy( -removedTrailingCharacters ); // Executed after a space character or punctuation.
const linkStart = linkEnd.getShiftedBy( -url.length );
const linkRange = editor.model.createRange( linkStart, linkEnd );
diff --git a/packages/ckeditor5-link/tests/autolink.js b/packages/ckeditor5-link/tests/autolink.js
index 406352bc590..78314c73007 100644
--- a/packages/ckeditor5-link/tests/autolink.js
+++ b/packages/ckeditor5-link/tests/autolink.js
@@ -454,6 +454,16 @@ describe( 'AutoLink', () => {
sinon.assert.notCalled( spy );
} );
+ for ( const punctuation of '!.:,;?' ) {
+ it( `does not include "${ punctuation }" at the end of the link after space`, () => {
+ simulateTyping( `https://www.cksource.com${ punctuation } ` );
+
+ expect( getData( model ) ).to.equal(
+ `<$text linkHref="https://www.cksource.com">https://www.cksource.com$text>${ punctuation } []`
+ );
+ } );
+ }
+
// Some examples came from https://mathiasbynens.be/demo/url-regex.
describe( 'supported URL', () => {
const supportedURLs = [