From d23adc5d5226f0abcfcf04f34e65a8f5380aa009 Mon Sep 17 00:00:00 2001 From: Mateusz Baginski Date: Fri, 20 Dec 2024 09:48:28 +0100 Subject: [PATCH] Add support of punctuation in autolinks. --- packages/ckeditor5-link/src/autolink.ts | 27 +++++++++++++++++------ packages/ckeditor5-link/tests/autolink.js | 10 +++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) 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${ punctuation } []` + ); + } ); + } + // Some examples came from https://mathiasbynens.be/demo/url-regex. describe( 'supported URL', () => { const supportedURLs = [