Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions packages/block-library/src/embed/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import {
createUpgradedEmbedBlock,
getClassNames,
removeAspectRatioClasses,
fallback,
getEmbedInfoByProvider,
getMergedAttributesWithPreview,
Expand Down Expand Up @@ -99,16 +100,14 @@ const EmbedEdit = ( props ) => {
/**
* Returns the attributes derived from the preview, merged with the current attributes.
*
* @param {boolean} ignorePreviousClassName Determines if the previous className attribute should be ignored when merging.
* @return {Object} Merged attributes.
*/
const getMergedAttributes = ( ignorePreviousClassName = false ) =>
const getMergedAttributes = () =>
getMergedAttributesWithPreview(
attributes,
preview,
title,
responsive,
ignorePreviousClassName
responsive
);

const toggleResponsive = () => {
Expand Down Expand Up @@ -136,21 +135,20 @@ const EmbedEdit = ( props ) => {
setURL( newURL );
setIsEditingURL( false );
setAttributes( { url: newURL } );
}, [ preview?.html, attributesUrl ] );
}, [ preview?.html, attributesUrl, cannotEmbed, fetching ] );

// Handle incoming preview.
useEffect( () => {
if ( preview && ! isEditingURL ) {
// When obtaining an incoming preview, we set the attributes derived from
// the preview data. In this case when getting the merged attributes,
// we ignore the previous classname because it might not match the expected
// classes by the new preview.
setAttributes( getMergedAttributes( true ) );
// When obtaining an incoming preview,
// we set the attributes derived from the preview data.
const mergedAttributes = getMergedAttributes();
setAttributes( mergedAttributes );

if ( onReplace ) {
const upgradedBlock = createUpgradedEmbedBlock(
props,
getMergedAttributes()
mergedAttributes
);

if ( upgradedBlock ) {
Expand Down Expand Up @@ -188,8 +186,14 @@ const EmbedEdit = ( props ) => {
event.preventDefault();
}

// If the embed URL was changed, we need to reset the aspect ratio class.
// To do this we have to remove the existing ratio class so it can be recalculated.
const blockClass = removeAspectRatioClasses(
attributes.className
);

setIsEditingURL( false );
setAttributes( { url } );
setAttributes( { url, className: blockClass } );
} }
value={ url }
cannotEmbed={ cannotEmbed }
Expand Down
12 changes: 12 additions & 0 deletions packages/block-library/src/embed/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
createUpgradedEmbedBlock,
getEmbedInfoByProvider,
removeAspectRatioClasses,
hasAspectRatioClass,
} from '../util';
import { embedInstagramIcon } from '../icons';
import variations from '../variations';
Expand Down Expand Up @@ -101,6 +102,17 @@ describe( 'utils', () => {
).toEqual( expected );
} );
} );
describe( 'hasAspectRatioClass', () => {
it( 'should return false if an aspect ratio class does not exist', () => {
const existingClassNames = 'wp-block-embed is-type-video';
expect( hasAspectRatioClass( existingClassNames ) ).toBe( false );
} );
it( 'should return true if an aspect ratio class exists', () => {
const existingClassNames =
'wp-block-embed is-type-video wp-embed-aspect-16-9 wp-has-aspect-ratio';
expect( hasAspectRatioClass( existingClassNames ) ).toBe( true );
} );
} );
describe( 'removeAspectRatioClasses', () => {
it( 'should return the same falsy value as received', () => {
const existingClassNames = undefined;
Expand Down
37 changes: 29 additions & 8 deletions packages/block-library/src/embed/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,21 @@ export const createUpgradedEmbedBlock = (
} );
};

/**
* Determine if the block already has an aspect ratio class applied.
*
* @param {string} existingClassNames Existing block classes.
* @return {boolean} True or false if the classnames contain an aspect ratio class.
*/
export const hasAspectRatioClass = ( existingClassNames ) => {
if ( ! existingClassNames ) {
return false;
}
return ASPECT_RATIOS.some( ( { className } ) =>
existingClassNames.includes( className )
);
};

/**
* Removes all previously set aspect ratio related classes and return the rest
* existing class names.
Expand Down Expand Up @@ -283,6 +298,13 @@ export const getAttributesFromPreview = memoize(
attributes.providerNameSlug = providerNameSlug;
}

// Aspect ratio classes are removed when the embed URL is updated.
// If the embed already has an aspect ratio class, that means the URL has not changed.
// Which also means no need to regenerate it with getClassNames.
if ( hasAspectRatioClass( currentClassNames ) ) {
return attributes;
}

attributes.className = getClassNames(
html,
currentClassNames,
Expand All @@ -296,27 +318,26 @@ export const getAttributesFromPreview = memoize(
/**
* Returns the attributes derived from the preview, merged with the current attributes.
*
* @param {Object} currentAttributes The current attributes of the block.
* @param {Object} preview The preview data.
* @param {string} title The block's title, e.g. Twitter.
* @param {boolean} isResponsive Boolean indicating if the block supports responsive content.
* @param {boolean} ignorePreviousClassName Determines if the previous className attribute should be ignored when merging.
* @param {Object} currentAttributes The current attributes of the block.
* @param {Object} preview The preview data.
* @param {string} title The block's title, e.g. Twitter.
* @param {boolean} isResponsive Boolean indicating if the block supports responsive content.
* @return {Object} Merged attributes.
*/
export const getMergedAttributesWithPreview = (
currentAttributes,
preview,
title,
isResponsive,
ignorePreviousClassName = false
isResponsive
) => {
const { allowResponsive, className } = currentAttributes;

return {
...currentAttributes,
...getAttributesFromPreview(
preview,
title,
ignorePreviousClassName ? undefined : className,
className,
isResponsive,
allowResponsive
),
Expand Down