-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PostFormat suggestion: fix double parsing #56255
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,14 @@ import { Button, PanelBody } from '@wordpress/components'; | |
import { useDispatch, useSelect } from '@wordpress/data'; | ||
import { __, sprintf } from '@wordpress/i18n'; | ||
import { store as coreStore } from '@wordpress/core-data'; | ||
import { store as blockEditorStore } from '@wordpress/block-editor'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { POST_FORMATS } from '../post-format'; | ||
import { store as editorStore } from '../../store'; | ||
import { getSuggestedPostFormat } from '../../utils/get-suggested-post-format'; | ||
|
||
const getSuggestion = ( supportedFormats, suggestedPostFormat ) => { | ||
const formats = POST_FORMATS.filter( ( format ) => | ||
|
@@ -33,19 +35,22 @@ const PostFormatSuggestion = ( { | |
); | ||
|
||
export default function PostFormatPanel() { | ||
const { currentPostFormat, suggestion } = useSelect( ( select ) => { | ||
const { getEditedPostAttribute, getSuggestedPostFormat } = | ||
select( editorStore ); | ||
const supportedFormats = | ||
select( coreStore ).getThemeSupports().formats ?? []; | ||
return { | ||
currentPostFormat: getEditedPostAttribute( 'format' ), | ||
suggestion: getSuggestion( | ||
supportedFormats, | ||
getSuggestedPostFormat() | ||
), | ||
}; | ||
}, [] ); | ||
const { currentPostFormat, supportedFormats, blocks } = useSelect( | ||
( select ) => { | ||
const { getEditedPostAttribute } = select( editorStore ); | ||
return { | ||
currentPostFormat: getEditedPostAttribute( 'format' ), | ||
supportedFormats: | ||
select( coreStore ).getThemeSupports().formats, | ||
blocks: select( blockEditorStore ).getBlocks(), | ||
}; | ||
}, | ||
[] | ||
); | ||
const suggestion = getSuggestion( | ||
supportedFormats ?? [], | ||
getSuggestedPostFormat( blocks ) | ||
); | ||
Comment on lines
+50
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
|
||
const { editPost } = useDispatch( editorStore ); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -256,7 +256,9 @@ class NativeEditorProvider extends Component { | |
|
||
componentDidUpdate( prevProps ) { | ||
if ( ! prevProps.isReady && this.props.isReady ) { | ||
const blocks = this.props.blocks; | ||
const blocks = | ||
this.props.getEditedPostAttribute( 'blocks' ) || | ||
parse( this.props.getEditedPostContent() ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's something terribly wrong here on the native side, but that's out of the scope of this PR. The blocks in the block editor store should be available when the editor is ready, yet they aren't (causing some test failures). I've just restore the logic from |
||
const isUnsupportedBlock = ( { name } ) => | ||
name === getUnregisteredTypeHandlerName(); | ||
const unsupportedBlockNames = blocks | ||
|
@@ -277,7 +279,10 @@ class NativeEditorProvider extends Component { | |
// Let's request the HTML from the component's state directly. | ||
html = applyFilters( 'native.persist-html' ); | ||
} else { | ||
html = serialize( this.props.blocks ); | ||
const blocks = this.props.getEditedPostAttribute( 'blocks' ); | ||
html = blocks?.length | ||
? serialize( blocks ) | ||
: this.props.getEditedPostContent(); | ||
} | ||
|
||
const hasChanges = | ||
|
@@ -354,7 +359,6 @@ const ComposedNativeProvider = compose( [ | |
withSelect( ( select ) => { | ||
const { | ||
__unstableIsEditorReady: isEditorReady, | ||
getEditorBlocks, | ||
getEditedPostAttribute, | ||
getEditedPostContent, | ||
getEditorSettings, | ||
|
@@ -372,8 +376,8 @@ const ComposedNativeProvider = compose( [ | |
return { | ||
mode: getEditorMode(), | ||
isReady: isEditorReady(), | ||
blocks: getEditorBlocks(), | ||
title: getEditedPostAttribute( 'title' ), | ||
getEditedPostAttribute, | ||
getEditedPostContent, | ||
defaultEditorColors, | ||
defaultEditorGradients, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,6 @@ import { | |
getFreeformContentHandlerName, | ||
getDefaultBlockName, | ||
__unstableSerializeAndClean, | ||
parse, | ||
} from '@wordpress/blocks'; | ||
import { isInTheFuture, getDate } from '@wordpress/date'; | ||
import { addQueryArgs, cleanForSlug } from '@wordpress/url'; | ||
|
@@ -819,53 +818,12 @@ export function getEditedPostPreviewLink( state ) { | |
* is a single block within the post and it is of a type known to match a | ||
* default post format. Returns null if the format cannot be determined. | ||
* | ||
* @param {Object} state Global application state. | ||
* @deprecated | ||
* | ||
* @return {?string} Suggested post format. | ||
*/ | ||
export function getSuggestedPostFormat( state ) { | ||
const blocks = getEditorBlocks( state ); | ||
|
||
if ( blocks.length > 2 ) return null; | ||
|
||
let name; | ||
// If there is only one block in the content of the post grab its name | ||
// so we can derive a suitable post format from it. | ||
if ( blocks.length === 1 ) { | ||
name = blocks[ 0 ].name; | ||
// Check for core/embed `video` and `audio` eligible suggestions. | ||
if ( name === 'core/embed' ) { | ||
const provider = blocks[ 0 ].attributes?.providerNameSlug; | ||
if ( [ 'youtube', 'vimeo' ].includes( provider ) ) { | ||
name = 'core/video'; | ||
} else if ( [ 'spotify', 'soundcloud' ].includes( provider ) ) { | ||
name = 'core/audio'; | ||
} | ||
} | ||
} | ||
|
||
// If there are two blocks in the content and the last one is a text blocks | ||
// grab the name of the first one to also suggest a post format from it. | ||
if ( blocks.length === 2 && blocks[ 1 ].name === 'core/paragraph' ) { | ||
name = blocks[ 0 ].name; | ||
} | ||
|
||
// We only convert to default post formats in core. | ||
switch ( name ) { | ||
case 'core/image': | ||
return 'image'; | ||
case 'core/quote': | ||
case 'core/pullquote': | ||
return 'quote'; | ||
case 'core/gallery': | ||
return 'gallery'; | ||
case 'core/video': | ||
return 'video'; | ||
case 'core/audio': | ||
return 'audio'; | ||
default: | ||
return null; | ||
} | ||
export function getSuggestedPostFormat() { | ||
return null; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should properly deprecate this selector. |
||
} | ||
|
||
/** | ||
|
@@ -1098,21 +1056,9 @@ export const isPublishSidebarEnabled = createRegistrySelector( | |
/** | ||
* Return the current block list. | ||
* | ||
* @param {Object} state | ||
* @return {Array} Block list. | ||
*/ | ||
export const getEditorBlocks = createSelector( | ||
( state ) => { | ||
return ( | ||
getEditedPostAttribute( state, 'blocks' ) || | ||
parse( getEditedPostContent( state ) ) | ||
); | ||
}, | ||
( state ) => [ | ||
getEditedPostAttribute( state, 'blocks' ), | ||
getEditedPostContent( state ), | ||
] | ||
); | ||
export const getEditorBlocks = getBlockEditorSelector( 'getBlocks' ); | ||
|
||
/** | ||
* A block selection object. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be more performant to derive value inside the
mapSelect
, so we don't re-render the component on every block change.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, will have to revert to using the selector
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's my alternative PR #56679.