Skip to content

Commit

Permalink
Link format: auto link pasted urls (#55195)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored Oct 16, 2023
1 parent e33eead commit a5a1ab0
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 32 deletions.
45 changes: 22 additions & 23 deletions packages/block-editor/src/components/rich-text/use-paste-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,26 +56,6 @@ export function usePasteHandler( props ) {
return;
}

const transformed = formatTypes.reduce(
( accumlator, { __unstablePasteRule } ) => {
// Only allow one transform.
if ( __unstablePasteRule && accumlator === value ) {
accumlator = __unstablePasteRule( value, {
html,
plainText,
} );
}

return accumlator;
},
value
);

if ( transformed !== value ) {
onChange( transformed );
return;
}

const isInternal =
event.clipboardData.getData( 'rich-text' ) === 'true';

Expand Down Expand Up @@ -160,9 +140,28 @@ export function usePasteHandler( props ) {
} );

if ( typeof content === 'string' ) {
const valueToInsert = create( { html: content } );
addActiveFormats( valueToInsert, value.activeFormats );
onChange( insert( value, valueToInsert ) );
const transformed = formatTypes.reduce(
( accumlator, { __unstablePasteRule } ) => {
// Only allow one transform.
if ( __unstablePasteRule && accumlator === value ) {
accumlator = __unstablePasteRule( value, {
html,
plainText,
} );
}

return accumlator;
},
value
);

if ( transformed !== value ) {
onChange( transformed );
} else {
const valueToInsert = create( { html: content } );
addActiveFormats( valueToInsert, value.activeFormats );
onChange( insert( value, valueToInsert ) );
}
} else if ( content.length > 0 ) {
if ( onReplace && isEmpty( value ) ) {
onReplace( content, content.length - 1, -1 );
Expand Down
24 changes: 18 additions & 6 deletions packages/format-library/src/link/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
removeFormat,
slice,
isCollapsed,
insert,
create,
} from '@wordpress/rich-text';
import { isURL, isEmail } from '@wordpress/url';
import {
Expand Down Expand Up @@ -135,10 +137,6 @@ export const link = {
rel: 'rel',
},
__unstablePasteRule( value, { html, plainText } ) {
if ( isCollapsed( value ) ) {
return value;
}

const pastedText = ( html || plainText )
.replace( /<[^>]+>/g, '' )
.trim();
Expand All @@ -152,12 +150,26 @@ export const link = {
// Allows us to ask for this information when we get a report.
window.console.log( 'Created link:\n\n', pastedText );

return applyFormat( value, {
const format = {
type: name,
attributes: {
url: decodeEntities( pastedText ),
},
} );
};

if ( isCollapsed( value ) ) {
return insert(
value,
applyFormat(
create( { text: plainText } ),
format,
0,
plainText.length
)
);
}

return applyFormat( value, format );
},
edit: Edit,
};
37 changes: 34 additions & 3 deletions test/e2e/specs/editor/various/copy-cut-paste.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,7 @@ test.describe( 'Copy/cut/paste', () => {
test( 'should link selection', async ( { pageUtils, editor } ) => {
await editor.insertBlock( {
name: 'core/paragraph',
attributes: {
content: 'a',
},
attributes: { content: 'a' },
} );
await pageUtils.pressKeys( 'primary+a' );
pageUtils.setClipboardData( {
Expand All @@ -520,6 +518,39 @@ test.describe( 'Copy/cut/paste', () => {
] );
} );

test( 'should auto-link', async ( { pageUtils, editor } ) => {
await editor.insertBlock( {
name: 'core/paragraph',
attributes: { content: 'a' },
} );
pageUtils.setClipboardData( {
plainText: 'https://wordpress.org/gutenberg',
html: 'https://wordpress.org/gutenberg',
} );
await pageUtils.pressKeys( 'primary+v' );
expect( await editor.getBlocks() ).toMatchObject( [
{
name: 'core/paragraph',
attributes: {
content:
'<a href="https://wordpress.org/gutenberg">https://wordpress.org/gutenberg</a>a',
},
},
] );
} );

test( 'should embed on paste', async ( { pageUtils, editor } ) => {
await editor.insertBlock( { name: 'core/paragraph' } );
pageUtils.setClipboardData( {
plainText: 'https://www.youtube.com/watch?v=FcTLMTyD2DU',
html: 'https://www.youtube.com/watch?v=FcTLMTyD2DU',
} );
await pageUtils.pressKeys( 'primary+v' );
expect( await editor.getBlocks() ).toMatchObject( [
{ name: 'core/embed' },
] );
} );

test( 'should not link selection for non http(s) protocol', async ( {
pageUtils,
editor,
Expand Down

1 comment on commit a5a1ab0

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in a5a1ab0.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6531235721
📝 Reported issues:

Please sign in to comment.