Skip to content

Commit

Permalink
Merge pull request #12460 from ckeditor/ck/11040-auto-link-correction
Browse files Browse the repository at this point in the history
Fix (link): Fixed incorrect behavior when text before auto-linked url was removed by pressing backspace. Previously, the removed text was reinserted on backspace press. Closes #12447.
  • Loading branch information
scofalik authored Sep 15, 2022
2 parents d9500fe + fb0e1fc commit 38979ed
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
30 changes: 24 additions & 6 deletions packages/ckeditor5-link/src/autolink.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,26 +223,39 @@ export default class AutoLink extends Plugin {
}

/**
* Applies a link on a given range.
* Applies a link on a given range if the link should be applied.
*
* @param {String} url The URL to link.
* @param {module:engine/model/range~Range} range The text range to apply the link attribute to.
* @private
*/
_applyAutoLink( link, range ) {
_applyAutoLink( url, range ) {
const model = this.editor.model;
const deletePlugin = this.editor.plugins.get( 'Delete' );

const defaultProtocol = this.editor.config.get( 'link.defaultProtocol' );
const parsedUrl = addLinkProtocolIfApplicable( link, defaultProtocol );
const fullUrl = addLinkProtocolIfApplicable( url, defaultProtocol );

if ( !this.isEnabled || !isLinkAllowedOnRange( range, model ) || !linkHasProtocol( parsedUrl ) ) {
if ( !this.isEnabled || !isLinkAllowedOnRange( range, model ) || !linkHasProtocol( fullUrl ) || linkIsAlreadySet( range ) ) {
return;
}

this._persistAutoLink( fullUrl, range );
}

/**
* Enqueues autolink changes in the model.
*
* @param {String} url The URL to link.
* @param {module:engine/model/range~Range} range The text range to apply the link attribute to.
* @protected
*/
_persistAutoLink( url, range ) {
const model = this.editor.model;
const deletePlugin = this.editor.plugins.get( 'Delete' );

// Enqueue change to make undo step.
model.enqueueChange( writer => {
writer.setAttribute( 'linkHref', parsedUrl, range );
writer.setAttribute( 'linkHref', url, range );

model.enqueueChange( () => {
deletePlugin.requestUndoOnBackspace();
Expand All @@ -265,3 +278,8 @@ function getUrlAtTextEnd( text ) {
function isLinkAllowedOnRange( range, model ) {
return model.schema.checkAttributeInSelection( model.createSelection( range ), 'linkHref' );
}

function linkIsAlreadySet( range ) {
const item = range.start.nodeAfter;
return item && item.hasAttribute( 'linkHref' );
}
33 changes: 33 additions & 0 deletions packages/ckeditor5-link/tests/autolink.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,17 @@ describe( 'AutoLink', () => {
);
} );

it( 'does not autolink if link is already created', () => {
setData( model, '<paragraph><$text linkHref="http://www.cksource.com">http://www.cksource.com</$text>[]</paragraph>' );

const plugin = editor.plugins.get( 'AutoLink' );
const spy = sinon.spy( plugin, '_persistAutoLink' );

editor.execute( 'enter' );

sinon.assert.notCalled( spy );
} );

// Some examples came from https://mathiasbynens.be/demo/url-regex.
describe( 'supported URL', () => {
const supportedURLs = [
Expand Down Expand Up @@ -414,6 +425,28 @@ describe( 'AutoLink', () => {
'<paragraph>https://www.cksource.com []</paragraph>'
);
} );

// https://github.com/ckeditor/ckeditor5/issues/12447
it( 'should not undo auto-linking by pressing backspace after any other change has been made', () => {
const viewDocument = editor.editing.view.document;
const deleteEvent = new DomEventData(
viewDocument,
{ preventDefault: sinon.spy() },
{ direction: 'backward', unit: 'codePoint', sequence: 1 }
);

simulateTyping( ' abc' );

viewDocument.fire( 'delete', deleteEvent );
viewDocument.fire( 'delete', deleteEvent );
viewDocument.fire( 'delete', deleteEvent );
viewDocument.fire( 'delete', deleteEvent );
viewDocument.fire( 'delete', deleteEvent );

expect( getData( model ) ).to.equal(
'<paragraph><$text linkHref="https://www.cksource.com">https://www.cksource.co[]</$text></paragraph>'
);
} );
} );

describe( 'Code blocks integration', () => {
Expand Down

0 comments on commit 38979ed

Please sign in to comment.