Skip to content

Commit

Permalink
prep build 09/05
Browse files Browse the repository at this point in the history
  • Loading branch information
bph committed Sep 5, 2023
2 parents 52e3ce9 + 5149ab5 commit 872b41b
Show file tree
Hide file tree
Showing 77 changed files with 1,302 additions and 1,092 deletions.
15 changes: 3 additions & 12 deletions bin/cherry-pick.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,10 @@ async function fetchPRs() {
id,
number,
title,
closed_at,
pull_request,
} ) ).sort( ( a, b ) => {
/*
* `closed_at` and `pull_request.merged_at` are _usually_ the same,
* but let's prefer the latter if it's available.
*/
if ( a?.pull_request?.merged_at && b?.pull_request?.merged_at ) {
return new Date( a?.pull_request?.merged_at ) - new Date( b?.pull_request?.merged_at );
}
return new Date( a.closed_at ) - new Date( b.closed_at );
} );

} ) )
.filter( ( { pull_request } ) => !! pull_request?.merged_at )
.sort( ( a, b ) => new Date( a?.pull_request?.merged_at ) - new Date( b?.pull_request?.merged_at ) );

console.log( 'Found the following PRs to cherry-pick (sorted by closed date in ascending order): ' );
PRs.forEach( ( { number, title } ) =>
Expand Down
26 changes: 26 additions & 0 deletions docs/reference-guides/data/data-core-block-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,19 @@ _Returns_

- `boolean`: Whether block is first in multi-selection.

### isGroupable

Indicates if the provided blocks(by client ids) are groupable. We need to have at least one block, have a grouping block name set and be able to remove these blocks.

_Parameters_

- _state_ `Object`: Global application state.
- _clientIds_ `string[]`: Block client ids. If not passed the selected blocks client ids will be used.

_Returns_

- `boolean`: True if the blocks are groupable.

### isLastBlockChangePersistent

Returns true if the most recent block change is be considered persistent, or false otherwise. A persistent change is one committed by BlockEditorProvider via its `onChange` callback, in addition to `onInput`.
Expand Down Expand Up @@ -1141,6 +1154,19 @@ _Returns_

- `boolean`: Whether user is typing.

### isUngroupable

Indicates if a block is ungroupable. A block is ungroupable if it is a single grouping block with inner blocks. If a block has an `ungroup` transform, it is also ungroupable, without the requirement of being the default grouping block. Additionally a block can only be ungrouped if it has inner blocks and can be removed.

_Parameters_

- _state_ `Object`: Global application state.
- _clientId_ `string`: Client Id of the block. If not passed the selected block's client id will be used.

_Returns_

- `boolean`: True if the block is ungroupable.

### isValidTemplate

Returns whether the blocks matches the template or not.
Expand Down
158 changes: 107 additions & 51 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -529,32 +529,30 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
* @return string Filtered block content.
*/
function gutenberg_render_layout_support_flag( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$support_layout = block_has_support( $block_type, array( 'layout' ), false ) || block_has_support( $block_type, array( '__experimentalLayout' ), false );
$has_child_layout = isset( $block['attrs']['style']['layout']['selfStretch'] );
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$block_supports_layout = block_has_support( $block_type, array( 'layout' ), false ) || block_has_support( $block_type, array( '__experimentalLayout' ), false );
$layout_from_parent = $block['attrs']['style']['layout']['selfStretch'] ?? null;

if ( ! $support_layout
&& ! $has_child_layout ) {
if ( ! $block_supports_layout && ! $layout_from_parent ) {
return $block_content;
}

$outer_class_names = array();

if ( $has_child_layout && ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] || 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) ) {

if ( 'fixed' === $layout_from_parent || 'fill' === $layout_from_parent ) {
$container_content_class = wp_unique_id( 'wp-container-content-' );

$child_layout_styles = array();

if ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] && isset( $block['attrs']['style']['layout']['flexSize'] ) ) {
if ( 'fixed' === $layout_from_parent && isset( $block['attrs']['style']['layout']['flexSize'] ) ) {
$child_layout_styles[] = array(
'selector' => ".$container_content_class",
'declarations' => array(
'flex-basis' => $block['attrs']['style']['layout']['flexSize'],
'box-sizing' => 'border-box',
),
);
} elseif ( 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) {
} elseif ( 'fill' === $layout_from_parent ) {
$child_layout_styles[] = array(
'selector' => ".$container_content_class",
'declarations' => array(
Expand All @@ -572,15 +570,27 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
);

$outer_class_names[] = $container_content_class;
}

// Prep the processor for modifying the block output.
$processor = new WP_HTML_Tag_Processor( $block_content );

// Having no tags implies there are no tags onto which to add class names.
if ( ! $processor->next_tag() ) {
return $block_content;
}

// Return early if only child layout exists.
if ( ! $support_layout && ! empty( $outer_class_names ) ) {
$content = new WP_HTML_Tag_Processor( $block_content );
$content->next_tag();
$content->add_class( implode( ' ', $outer_class_names ) );
return (string) $content;
/*
* A block may not support layout but still be affected by a parent block's layout.
*
* In these cases add the appropriate class names and then return early; there's
* no need to investigate on this block whether additional layout constraints apply.
*/
if ( ! $block_supports_layout && ! empty( $outer_class_names ) ) {
foreach ( $outer_class_names as $class_name ) {
$processor->add_class( $class_name );
}
return $processor->get_updated_html();
}

$global_settings = gutenberg_get_global_settings();
Expand All @@ -590,7 +600,6 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$class_names = array();
$layout_definitions = gutenberg_get_layout_definitions();
$container_class = wp_unique_id( 'wp-container-' );
$layout_classname = '';

// Set the correct layout type for blocks using legacy content width.
if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] ) {
Expand All @@ -599,11 +608,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {

$root_padding_aware_alignments = _wp_array_get( $global_settings, array( 'useRootPaddingAwareAlignments' ), false );

if (
$root_padding_aware_alignments &&
isset( $used_layout['type'] ) &&
'constrained' === $used_layout['type']
) {
if ( $root_padding_aware_alignments && isset( $used_layout['type'] ) && 'constrained' === $used_layout['type'] ) {
$class_names[] = 'has-global-padding';
}

Expand Down Expand Up @@ -690,49 +695,100 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$full_block_name = 'core' === $split_block_name[0] ? end( $split_block_name ) : implode( '-', $split_block_name );
$class_names[] = 'wp-block-' . $full_block_name . '-' . $layout_classname;

$content_with_outer_classnames = '';

// Add classes to the outermost HTML tag if necessary.
if ( ! empty( $outer_class_names ) ) {
$content_with_outer_classnames = new WP_HTML_Tag_Processor( $block_content );
$content_with_outer_classnames->next_tag();
foreach ( $outer_class_names as $outer_class_name ) {
$content_with_outer_classnames->add_class( $outer_class_name );
$processor->add_class( $outer_class_name );
}

$content_with_outer_classnames = (string) $content_with_outer_classnames;
}

/**
* The first chunk of innerContent contains the block markup up until the inner blocks start.
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk.
*/
$inner_content_classnames = '';

if ( isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) && count( $block['innerContent'] ) > 1 ) {
$tags = new WP_HTML_Tag_Processor( $block['innerContent'][0] );
$last_classnames = '';
while ( $tags->next_tag() ) {
$last_classnames = $tags->get_attribute( 'class' );
* Attempts to refer to the inner-block wrapping element by its class attribute.
*
* When examining a block's inner content, if a block has inner blocks, then
* the first content item will likely be a text (HTML) chunk immediately
* preceding the inner blocks. The last HTML tag in that chunk would then be
* an opening tag for an element that wraps the inner blocks.
*
* There's no reliable way to associate this wrapper in $block_content because
* it may have changed during the rendering pipeline (as inner contents is
* provided before rendering) and through previous filters. In many cases,
* however, the `class` attribute will be a good-enough identifier, so this
* code finds the last tag in that chunk and stores the `class` attribute
* so that it can be used later when working through the rendered block output
* to identify the wrapping element and add the remaining class names to it.
*
* It's also possible that no inner block wrapper even exists. If that's the
* case this code could apply the class names to an invalid element.
*
* Example:
*
* $block['innerBlocks'] = array( $list_item );
* $block['innerContent'] = array( '<ul class="list-wrapper is-unordered">', null, '</ul>' );
*
* // After rendering, the initial contents may have been modified by other renderers or filters.
* $block_content = <<<HTML
* <figure>
* <ul class="annotated-list list-wrapper is-unordered">
* <li>Code</li>
* </ul><figcaption>It's a list!</figcaption>
* </figure>
* HTML;
*
* Although it is possible that the original block-wrapper classes are changed in $block_content
* from how they appear in $block['innerContent'], it's likely that the original class attributes
* are still present in the wrapper as they are in this example. Frequently, additional classes
* will also be present; rarely should classes be removed.
*
* @TODO: Find a better way to match the first inner block. If it's possible to identify where the
* first inner block starts, then it will be possible to find the last tag before it starts
* and then that tag, if an opening tag, can be solidly identified as a wrapping element.
* Can some unique value or class or ID be added to the inner blocks when they process
* so that they can be extracted here safely without guessing? Can the block rendering function
* return information about where the rendered inner blocks start?
*
* @var string|null
*/
$inner_block_wrapper_classes = null;
$first_chunk = $block['innerContent'][0] ?? null;
if ( is_string( $first_chunk ) && count( $block['innerContent'] ) > 1 ) {
$first_chunk_processor = new WP_HTML_Tag_Processor( $first_chunk );
while ( $first_chunk_processor->next_tag() ) {
$class_attribute = $first_chunk_processor->get_attribute( 'class' );
if ( is_string( $class_attribute ) && ! empty( $class_attribute ) ) {
$inner_block_wrapper_classes = $class_attribute;
}
}

$inner_content_classnames = (string) $last_classnames;
}

$content = $content_with_outer_classnames ? new WP_HTML_Tag_Processor( $content_with_outer_classnames ) : new WP_HTML_Tag_Processor( $block_content );

if ( $inner_content_classnames ) {
$content->next_tag( array( 'class_name' => $inner_content_classnames ) );
foreach ( $class_names as $class_name ) {
$content->add_class( $class_name );
/*
* If necessary, advance to what is likely to be an inner block wrapper tag.
*
* This advances until it finds the first tag containing the original class
* attribute from above. If none is found it will scan to the end of the block
* and fail to add any class names.
*
* If there is no block wrapper it won't advance at all, in which case the
* class names will be added to the first and outermost tag of the block.
* For cases where this outermost tag is the only tag surrounding inner
* blocks then the outer wrapper and inner wrapper are the same.
*/
do {
if ( ! $inner_block_wrapper_classes ) {
break;
}
} else {
$content->next_tag();
foreach ( $class_names as $class_name ) {
$content->add_class( $class_name );

if ( false !== strpos( $processor->get_attribute( 'class' ), $inner_block_wrapper_classes ) ) {
break;
}
} while ( $processor->next_tag() );

// Add the remaining class names.
foreach ( $class_names as $class_name ) {
$processor->add_class( $class_name );
}

return (string) $content;
return $processor->get_updated_html();
}

// Register the block support. (overrides core one).
Expand Down
2 changes: 0 additions & 2 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ function gutenberg_reregister_core_block_types() {
'code',
'column',
'columns',
'comments',
'details',
'group',
'footnotes',
'html',
'list',
'list-item',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,15 @@ const BlockSettingsMenuControlsSlot = ( {
clientIds = null,
__unstableDisplayLocation,
} ) => {
const { selectedBlocks, selectedClientIds, canRemove } = useSelect(
const { selectedBlocks, selectedClientIds } = useSelect(
( select ) => {
const {
getBlockNamesByClientId,
getSelectedBlockClientIds,
canRemoveBlocks,
} = select( blockEditorStore );
const { getBlockNamesByClientId, getSelectedBlockClientIds } =
select( blockEditorStore );
const ids =
clientIds !== null ? clientIds : getSelectedBlockClientIds();
return {
selectedBlocks: getBlockNamesByClientId( ids ),
selectedClientIds: ids,
canRemove: canRemoveBlocks( ids ),
};
},
[ clientIds ]
Expand All @@ -55,8 +51,7 @@ const BlockSettingsMenuControlsSlot = ( {
const convertToGroupButtonProps =
useConvertToGroupButtonProps( selectedClientIds );
const { isGroupable, isUngroupable } = convertToGroupButtonProps;
const showConvertToGroupButton =
( isGroupable || isUngroupable ) && canRemove;
const showConvertToGroupButton = isGroupable || isUngroupable;

return (
<Slot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ const BlockActionsMenu = ( {
rootClientId,
selectedBlockClientId,
selectedBlockPossibleTransformations,
canRemove,
// Dispatch.
createSuccessNotice,
convertToRegularBlocks,
Expand Down Expand Up @@ -106,8 +105,7 @@ const BlockActionsMenu = ( {
selectedBlockClientId ? [ selectedBlockClientId ] : []
);
const { isGroupable, isUngroupable } = convertToGroupButtonProps;
const showConvertToGroupButton =
( isGroupable || isUngroupable ) && canRemove;
const showConvertToGroupButton = isGroupable || isUngroupable;
const convertToGroupButtons = useConvertToGroupButtons( {
...convertToGroupButtonProps,
} );
Expand Down Expand Up @@ -348,7 +346,6 @@ export default compose(
getSelectedBlockClientIds,
canInsertBlockType,
getTemplateLock,
canRemoveBlock,
} = select( blockEditorStore );
const block = getBlock( clientId );
const blockName = getBlockName( clientId );
Expand Down Expand Up @@ -385,7 +382,6 @@ export default compose(
const selectedBlockPossibleTransformations = selectedBlock
? getBlockTransformItems( selectedBlock, rootClientId )
: EMPTY_BLOCK_LIST;
const canRemove = canRemoveBlock( selectedBlockClientId );

const isReusableBlockType = block ? isReusableBlock( block ) : false;
const reusableBlock = isReusableBlockType
Expand All @@ -411,7 +407,6 @@ export default compose(
rootClientId,
selectedBlockClientId,
selectedBlockPossibleTransformations,
canRemove,
};
} ),
withDispatch(
Expand Down
Loading

0 comments on commit 872b41b

Please sign in to comment.