diff --git a/assets/css/src/amp-block-editor.css b/assets/css/src/amp-block-editor.css
index db36813bb0c..7a3a704efb5 100644
--- a/assets/css/src/amp-block-editor.css
+++ b/assets/css/src/amp-block-editor.css
@@ -1,8 +1,3 @@
-.is-amp-fit-text + .blocks-font-size > .components-font-size-picker__buttons,
-.is-amp-fit-text + .blocks-font-size > .components-font-size-picker__custom-input {
- display: none;
-}
-
/* AMP preview button wrapper */
.wp-core-ui .amp-wrapper-post-preview {
margin-left: -6px;
diff --git a/assets/css/src/amp-default.css b/assets/css/src/amp-default.css
index 43cc0027008..28dc272106a 100644
--- a/assets/css/src/amp-default.css
+++ b/assets/css/src/amp-default.css
@@ -11,16 +11,6 @@ amp-anim.amp-wp-enforced-sizes[layout="intrinsic"] > img {
object-fit: contain;
}
-amp-fit-text blockquote,
-amp-fit-text h1,
-amp-fit-text h2,
-amp-fit-text h3,
-amp-fit-text h4,
-amp-fit-text h5,
-amp-fit-text h6 {
- font-size: inherit;
-}
-
/**
* Override a style rule in Twenty Sixteen and Twenty Seventeen.
* It set display:none for audio elements.
diff --git a/assets/src/block-editor/helpers/index.js b/assets/src/block-editor/helpers/index.js
index 1a051f8f5e0..e23fa30b84c 100644
--- a/assets/src/block-editor/helpers/index.js
+++ b/assets/src/block-editor/helpers/index.js
@@ -7,11 +7,11 @@ import { ReactElement } from 'react';
/**
* WordPress dependencies
*/
-import { __, _x, sprintf } from '@wordpress/i18n';
-import { cloneElement } from '@wordpress/element';
-import { TextControl, SelectControl, ToggleControl, Notice, PanelBody, FontSizePicker } from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { SelectControl, ToggleControl, Notice, PanelBody } from '@wordpress/components';
import { InspectorControls } from '@wordpress/block-editor';
import { select } from '@wordpress/data';
+import { cloneElement } from '@wordpress/element';
/**
* Internal dependencies
@@ -115,38 +115,6 @@ export const addAMPAttributes = ( settings, name ) => {
};
}
- const isTextBlock = TEXT_BLOCKS.includes( name );
-
- // Fit-text for text blocks.
- if ( isTextBlock ) {
- if ( ! settings.attributes ) {
- settings.attributes = {};
- }
- settings.attributes.ampFitText = {
- type: 'boolean',
- default: false,
- };
- settings.attributes.minFont = {
- default: MIN_FONT_SIZE,
- source: 'attribute',
- selector: 'amp-fit-text',
- attribute: 'min-font-size',
- };
- settings.attributes.maxFont = {
- default: MAX_FONT_SIZE,
- source: 'attribute',
- selector: 'amp-fit-text',
- attribute: 'max-font-size',
- };
- settings.attributes.height = {
- // Needs to be higher than the maximum font size, which defaults to MAX_FONT_SIZE
- default: 'core/image' === name ? 200 : Math.ceil( MAX_FONT_SIZE / 10 ) * 10,
- source: 'attribute',
- selector: 'amp-fit-text',
- attribute: 'height',
- };
- }
-
// Layout settings for embeds and media blocks.
if ( 0 === name.indexOf( 'core-embed' ) || MEDIA_BLOCKS.includes( name ) ) {
if ( ! settings.attributes ) {
@@ -163,68 +131,102 @@ export const addAMPAttributes = ( settings, name ) => {
};
/**
- * Filters blocks' save function.
+ * Removes `amp-fit-text` related attributes on blocks via block deprecation.
*
- * @param {Object} element Element to be saved.
- * @param {string} blockType Block type.
- * @param {string} blockType.name Block type name.
- * @param {Object} attributes Attributes.
+ * @param {Object} settings Block settings.
+ * @param {string} name Block name.
*
- * @return {Object} Output element.
+ * @return {Object} Modified block settings.
*/
-export const filterBlocksSave = ( element, blockType, attributes ) => { // eslint-disable-line complexity
- const fitTextProps = {
- layout: 'fixed-height',
- };
-
- if ( 'core/paragraph' === blockType.name && ! attributes.ampFitText ) {
- const content = getAmpFitTextContent( attributes.content );
- if ( content !== attributes.content ) {
- return cloneElement(
- element,
- {
- key: 'new',
- value: content,
- },
- );
- }
- } else if ( TEXT_BLOCKS.includes( blockType.name ) && attributes.ampFitText ) {
- if ( attributes.minFont ) {
- fitTextProps[ 'min-font-size' ] = attributes.minFont;
- }
- if ( attributes.maxFont ) {
- fitTextProps[ 'max-font-size' ] = attributes.maxFont;
- }
- if ( attributes.height ) {
- fitTextProps.height = attributes.height;
+export const removeAmpFitTextFromBlocks = ( settings, name ) => {
+ if ( TEXT_BLOCKS.includes( name ) ) {
+ if ( ! settings.deprecated ) {
+ settings.deprecated = [];
}
- fitTextProps.children = element;
-
- return ;
+ settings.deprecated.unshift( {
+ supports: settings.supports,
+ attributes: {
+ ...( settings.attributes || {} ),
+ ampFitText: {
+ type: 'boolean',
+ default: false,
+ },
+ minFont: {
+ default: MIN_FONT_SIZE,
+ source: 'attribute',
+ selector: 'amp-fit-text',
+ attribute: 'min-font-size',
+ },
+ maxFont: {
+ default: MAX_FONT_SIZE,
+ source: 'attribute',
+ selector: 'amp-fit-text',
+ attribute: 'max-font-size',
+ },
+ height: {
+ // Needs to be higher than the maximum font size, which defaults to MAX_FONT_SIZE
+ default: 'core/image' === name ? 200 : Math.ceil( MAX_FONT_SIZE / 10 ) * 10,
+ source: 'attribute',
+ selector: 'amp-fit-text',
+ attribute: 'height',
+ },
+ },
+ save( props ) {
+ /* eslint-disable react/prop-types */
+ const { attributes } = props;
+ const fitTextProps = { layout: 'fixed-height' };
+
+ if ( attributes.minFont ) {
+ fitTextProps[ 'min-font-size' ] = attributes.minFont;
+ }
+ if ( attributes.maxFont ) {
+ fitTextProps[ 'max-font-size' ] = attributes.maxFont;
+ }
+ if ( attributes.height ) {
+ fitTextProps.height = attributes.height;
+ }
+ /* eslint-enable react/prop-types */
+
+ fitTextProps.children = settings.save( props );
+
+ return ;
+ },
+ isEligible( { ampFitText } ) {
+ return undefined !== ampFitText;
+ },
+ migrate( attributes ) {
+ const deprecatedAttrs = [ 'ampFitText', 'minFont', 'maxFont', 'height' ];
+ deprecatedAttrs.forEach( ( attr ) => delete attributes[ attr ] );
+ return attributes;
+ },
+ } );
}
- return element;
+ return settings;
};
/**
- * Returns the inner content of an AMP Fit Text tag.
+ * Remove the `class` attribute from `amp-fit-text` elements so that it can be deprecated successfully.
+ *
+ * The `class` attribute is added by the `core/generated-class-name/save-props` block editor filter; it is unwanted and
+ * interferes with successful deprecation of the block. By filtering the saved element the `class` attribute can be
+ * removed and the deprecation of the block and proceed without error.
+ *
+ * @see removeAmpFitTextFromBlocks
*
- * @param {string} content Original content.
+ * @param {ReactElement} element Block save result.
*
- * @return {string} Modified content.
+ * @return {ReactElement} Modified block if it is of `amp-fit-text` type, otherwise the original element is returned.
*/
-export const getAmpFitTextContent = ( content ) => {
- const contentRegex = /]*>(.*?)<\/amp-fit-text>/;
- const match = contentRegex.exec( content );
-
- let newContent = content;
-
- if ( match && match[ 1 ] ) {
- newContent = match[ 1 ];
+export const removeClassFromAmpFitTextBlocks = ( element ) => {
+ if ( 'amp-fit-text' === element.type && undefined !== element.props.className ) {
+ const { className, ...props } = element.props;
+ props.className = null;
+ element = cloneElement( element, props );
}
- return newContent;
+ return element;
};
/**
@@ -275,8 +277,6 @@ export const filterBlocksEdit = ( BlockEdit ) => {
inspectorControls = setUpImageInspectorControls( props );
} else if ( MEDIA_BLOCKS.includes( name ) || 0 === name.indexOf( 'core-embed/' ) ) {
inspectorControls = setUpInspectorControls( props );
- } else if ( TEXT_BLOCKS.includes( name ) ) {
- inspectorControls = setUpTextBlocksInspectorControls( props );
}
// Return just inspector controls in case of 'nodisplay'.
@@ -478,146 +478,6 @@ AmpNoloadingToggle.propTypes = {
setAttributes: PropTypes.func.isRequired,
};
-/**
- * Setup inspector controls for text blocks.
- *
- * @todo Consider wrapping the render function to delete the original font size in text settings when ampFitText.
- *
- * @param {Object} props Props.
- * @param {Function} props.setAttributes Callback to set attributes.
- * @param {Object} props.attributes Attributes.
- * @param {boolean} props.isSelected Is selected.
- *
- * @return {ReactElement} Inspector Controls.
- */
-const setUpTextBlocksInspectorControls = ( props ) => {
- const { isSelected, attributes, setAttributes } = props;
- const { ampFitText } = attributes;
- let { minFont, maxFont, height } = attributes;
-
- const FONT_SIZES = [
- {
- name: 'small',
- shortName: _x( 'S', 'font size', 'amp' ),
- size: 14,
- },
- {
- name: 'regular',
- shortName: _x( 'M', 'font size', 'amp' ),
- size: 16,
- },
- {
- name: 'large',
- shortName: _x( 'L', 'font size', 'amp' ),
- size: 36,
- },
- {
- name: 'larger',
- shortName: _x( 'XL', 'font size', 'amp' ),
- size: 48,
- },
- ];
-
- if ( ! isSelected ) {
- return null;
- }
-
- const label = __( 'Automatically fit text to container', 'amp' );
-
- if ( ampFitText ) {
- maxFont = parseInt( maxFont );
- height = parseInt( height );
- minFont = parseInt( minFont );
- }
-
- return (
-
-
- setAttributes( { ampFitText: ! ampFitText } ) }
- />
-
- { ampFitText && (
- <>
- {
- setAttributes( { height: nextHeight } );
- } }
- />
- { maxFont > height && (
-
- { __( 'The height must be greater than the max font size.', 'amp' ) }
-
- ) }
-
- {
- if ( ! nextMinFont ) {
- nextMinFont = MIN_FONT_SIZE; // @todo Supplying fallbackFontSize should be done automatically by the component?
- }
-
- if ( parseInt( nextMinFont ) <= maxFont ) {
- setAttributes( { minFont: nextMinFont } );
- }
- } }
- />
-
- { minFont > maxFont && (
-
- { __( 'The min font size must less than the max font size.', 'amp' ) }
-
- ) }
-
- {
- if ( ! nextMaxFont ) {
- nextMaxFont = MAX_FONT_SIZE; // @todo Supplying fallbackFontSize should be done automatically by the component?
- }
-
- setAttributes( {
- maxFont: nextMaxFont,
- height: Math.max( nextMaxFont, height ),
- } );
- } }
- />
-
- >
- ) }
-
- );
-};
-
-setUpTextBlocksInspectorControls.propTypes = {
- isSelected: PropTypes.bool,
- attributes: PropTypes.shape( {
- ampFitText: PropTypes.bool,
- minFont: PropTypes.number,
- maxFont: PropTypes.number,
- height: PropTypes.number,
- } ),
- setAttributes: PropTypes.func.isRequired,
-};
-
/**
* Get AMP Lightbox toggle control.
*
diff --git a/assets/src/block-editor/helpers/test/getAmpFitTextContent.js b/assets/src/block-editor/helpers/test/getAmpFitTextContent.js
deleted file mode 100644
index d70e903c45b..00000000000
--- a/assets/src/block-editor/helpers/test/getAmpFitTextContent.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Internal dependencies
- */
-import { getAmpFitTextContent } from '../';
-
-describe( 'getAmpFitTextContent', () => {
- it( 'should extract the element\'s content', () => {
- const result = getAmpFitTextContent( 'Hello World' );
- expect( result ).toBe( 'Hello World' );
- } );
-
- it( 'should extract the element\'s content even when there are some attributes', () => {
- const result = getAmpFitTextContent( 'Hello World' );
- expect( result ).toBe( 'Hello World' );
- } );
-} );
diff --git a/assets/src/block-editor/index.js b/assets/src/block-editor/index.js
index 5300f00990a..dc238acd3c0 100644
--- a/assets/src/block-editor/index.js
+++ b/assets/src/block-editor/index.js
@@ -12,7 +12,7 @@ import { select } from '@wordpress/data';
import { withFeaturedImageNotice } from '../common/components';
import { getMinimumFeaturedImageDimensions } from '../common/helpers';
import { withMediaLibraryNotice } from './components';
-import { addAMPAttributes, filterBlocksEdit, filterBlocksSave } from './helpers';
+import { addAMPAttributes, filterBlocksEdit, removeAmpFitTextFromBlocks, removeClassFromAmpFitTextBlocks } from './helpers';
import './store';
const {
@@ -28,7 +28,8 @@ plugins.keys().forEach( ( modulePath ) => {
} );
addFilter( 'blocks.registerBlockType', 'ampEditorBlocks/addAttributes', addAMPAttributes );
-addFilter( 'blocks.getSaveElement', 'ampEditorBlocks/filterSave', filterBlocksSave );
+addFilter( 'blocks.registerBlockType', 'ampEditorBlocks/deprecateAmpFitText', removeAmpFitTextFromBlocks );
+addFilter( 'blocks.getSaveElement', 'ampEditorBlocks/deprecateAmpFitText/removeMiscAttrs', removeClassFromAmpFitTextBlocks );
addFilter( 'editor.BlockEdit', 'ampEditorBlocks/filterEdit', filterBlocksEdit, 20 );
addFilter( 'editor.PostFeaturedImage', 'ampEditorBlocks/withFeaturedImageNotice', withFeaturedImageNotice );
addFilter( 'editor.MediaUpload', 'ampEditorBlocks/withMediaLibraryNotice', ( InitialMediaUpload ) => withMediaLibraryNotice( InitialMediaUpload, getMinimumFeaturedImageDimensions() ) );
diff --git a/includes/admin/class-amp-editor-blocks.php b/includes/admin/class-amp-editor-blocks.php
index 543667740ea..dc420037b78 100644
--- a/includes/admin/class-amp-editor-blocks.php
+++ b/includes/admin/class-amp-editor-blocks.php
@@ -35,7 +35,6 @@ class AMP_Editor_Blocks {
'amp-jwplayer',
'amp-brid-player',
'amp-ima-video',
- 'amp-fit-text',
];
/**