Skip to content

Commit

Permalink
Merge branch 'trunk' into fix/pattern-explorer-regression
Browse files Browse the repository at this point in the history
  • Loading branch information
Mamaduka committed Feb 2, 2023
2 parents 7ced493 + b0275ae commit d078387
Show file tree
Hide file tree
Showing 33 changed files with 775 additions and 197 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/end2end-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:
fail-fast: false
matrix:
part: [1, 2, 3, 4]
totalParts: [4]

steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
Expand All @@ -46,7 +47,7 @@ jobs:
- name: Running the tests
run: |
$( npm bin )/wp-scripts test-e2e --config=./packages/e2e-tests/jest.config.js --listTests > ~/.jest-e2e-tests
$( npm bin )/wp-scripts test-e2e --config=./packages/e2e-tests/jest.config.js --cacheDirectory="$HOME/.jest-cache" --runTestsByPath $( awk 'NR % 4 == ${{ matrix.part }} - 1' < ~/.jest-e2e-tests )
$( npm bin )/wp-scripts test-e2e --config=./packages/e2e-tests/jest.config.js --cacheDirectory="$HOME/.jest-cache" --runTestsByPath $( awk 'NR % ${{ matrix.totalParts }} == ${{ matrix.part }} - 1' < ~/.jest-e2e-tests )
- name: Archive debug artifacts (screenshots, HTML snapshots)
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
Expand All @@ -65,11 +66,14 @@ jobs:
if-no-files-found: ignore

e2e-playwright:
name: Playwright
name: Playwright - ${{ matrix.part }}
runs-on: ubuntu-latest
if: ${{ github.repository == 'WordPress/gutenberg' || github.event_name == 'pull_request' }}
strategy:
fail-fast: false
matrix:
part: [1, 2]
totalParts: [2]

steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
Expand All @@ -95,7 +99,7 @@ jobs:
- name: Run the tests
run: |
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:playwright
xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:e2e:playwright -- --shard=${{ matrix.part }}/${{ matrix.totalParts }}
- name: Archive debug artifacts (screenshots, traces)
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,4 @@ jobs:
env:
COMMITTED_AT: ${{ steps.commit-timestamp.outputs.result }}
CODEHEALTH_PROJECT_TOKEN: ${{ secrets.CODEHEALTH_PROJECT_TOKEN }}
run: ./bin/log-perormance-results.js $CODEHEALTH_PROJECT_TOKEN trunk $GITHUB_SHA debd225d007f4e441ceec80fbd6fa96653f94737 $COMMITTED_AT
run: ./bin/log-performance-results.js $CODEHEALTH_PROJECT_TOKEN trunk $GITHUB_SHA debd225d007f4e441ceec80fbd6fa96653f94737 $COMMITTED_AT
File renamed without changes.
12 changes: 12 additions & 0 deletions docs/reference-guides/block-api/block-registration.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,18 @@ Setting `parent` lets a block require that it is only available when nested with
parent: [ 'core/columns' ],
```

#### ancestor (optional)

- **Type:** `Array`

The `ancestor` property makes a block available inside the specified block types at any position of the ancestor block subtree. That allows, for example, to place a 'Comment Content' block inside a 'Column' block, as long as 'Column' is somewhere within a 'Comment Template' block. In comparison to the `parent` property blocks that specify their `ancestor` can be placed anywhere in the subtree whilst blocks with a specified `parent` need to be direct children.


```js
// Only allow this block when it is nested at any level in a Columns block.
ancestor: [ 'core/columns' ],
```

## Block Collections

## `registerBlockCollection`
Expand Down
67 changes: 41 additions & 26 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,14 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n
$schema_settings_blocks = array();
foreach ( $valid_block_names as $block ) {
// Build the schema for each block style variation.
$style_variation_names = isset( $input['styles']['blocks'][ $block ]['variations'] ) ? array_keys( $input['styles']['blocks'][ $block ]['variations'] ) : array();
$style_variation_names = array();
if (
! empty( $input['styles']['blocks'][ $block ]['variations'] ) &&
is_array( $input['styles']['blocks'][ $block ]['variations'] )
) {
$style_variation_names = array_keys( $input['styles']['blocks'][ $block ]['variations'] );
}

$schema_styles_variations = array();
if ( ! empty( $style_variation_names ) ) {
$schema_styles_variations = array_fill_keys( $style_variation_names, $styles_non_top_level );
Expand Down Expand Up @@ -2315,33 +2322,41 @@ public function get_styles_for_block( $block_metadata ) {

// If the block has feature selectors, generate the declarations for them within the current style variation.
if ( ! empty( $block_metadata['features'] ) ) {
$clean_style_variation_selector = trim( $style_variation_selector );
foreach ( $block_metadata['features'] as $feature_name => $feature_selector ) {
if ( ! empty( $style_variation_node[ $feature_name ] ) ) {
// Prepend the variation selector to the feature selector.
$split_feature_selectors = explode( ',', $feature_selector );
$feature_selectors = array_map(
function( $split_feature_selector ) use ( $style_variation_selector ) {
return trim( $style_variation_selector ) . trim( $split_feature_selector );
},
$split_feature_selectors
);
$combined_feature_selectors = implode( ',', $feature_selectors );

// Compute declarations for the feature.
$new_feature_declarations = static::compute_style_properties( array( $feature_name => $style_variation_node[ $feature_name ] ), $settings, null, $this->theme_json );

// Merge new declarations with any that already exist for
// the feature selector. This may occur when multiple block
// support features use the same custom selector.
if ( isset( $style_variation_declarations[ $combined_feature_selectors ] ) ) {
$style_variation_declarations[ $combined_feature_selectors ] = array_merge( $style_variation_declarations[ $combined_feature_selectors ], $new_feature_declarations );
} else {
$style_variation_declarations[ $combined_feature_selectors ] = $new_feature_declarations;
}
// Remove the feature from the variation's node now the
// styles will be included under the feature level selector.
unset( $style_variation_node[ $feature_name ] );
if ( empty( $style_variation_node[ $feature_name ] ) ) {
continue;
}
// Prepend the variation selector to the feature selector.
$split_feature_selectors = explode( ',', $feature_selector );
$feature_selectors = array_map(
static function( $split_feature_selector ) use ( $clean_style_variation_selector ) {
return $clean_style_variation_selector . trim( $split_feature_selector );
},
$split_feature_selectors
);
$combined_feature_selectors = implode( ',', $feature_selectors );

// Compute declarations for the feature.
$new_feature_declarations = static::compute_style_properties( array( $feature_name => $style_variation_node[ $feature_name ] ), $settings, null, $this->theme_json );

/*
* Merge new declarations with any that already exist for
* the feature selector. This may occur when multiple block
* support features use the same custom selector.
*/
if ( isset( $style_variation_declarations[ $combined_feature_selectors ] ) ) {
$style_variation_declarations[ $combined_feature_selectors ] = array_merge( $style_variation_declarations[ $combined_feature_selectors ], $new_feature_declarations );
} else {
$style_variation_declarations[ $combined_feature_selectors ] = $new_feature_declarations;
}

/*
* Remove the feature from the variation's node now the
* styles will be included under the feature level selector.
*/
unset( $style_variation_node[ $feature_name ] );

}
}
// Compute declarations for remaining styles not covered by feature level selectors.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import DownloadableBlocksInserterPanel from './inserter-panel';
import DownloadableBlocksNoResults from './no-results';
import { store as blockDirectoryStore } from '../../store';

const EMPTY_ARRAY = [];

function DownloadableBlocksPanel( {
downloadableItems,
onSelect,
Expand Down Expand Up @@ -81,14 +83,25 @@ export default compose( [
);

function getInstallableBlocks( term ) {
return getDownloadableBlocks( term ).filter( ( block ) =>
const downloadableBlocks = getDownloadableBlocks( term );
const installableBlocks = downloadableBlocks.filter( ( block ) =>
canInsertBlockType( block, rootClientId, true )
);

if ( downloadableBlocks.length === installableBlocks.length ) {
return downloadableBlocks;
}
return installableBlocks;
}

const downloadableItems = hasPermission
let downloadableItems = hasPermission
? getInstallableBlocks( filterValue )
: [];

if ( downloadableItems.length === 0 ) {
downloadableItems = EMPTY_ARRAY;
}

const isLoading = isRequestingDownloadableBlocks( filterValue );

return {
Expand Down
9 changes: 9 additions & 0 deletions packages/block-editor/src/components/block-actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export default function BlockActions( {
setBlockMovingClientId,
setNavigationMode,
selectBlock,
clearSelectedBlock,
multiSelect,
} = useDispatch( blockEditorStore );

const notifyCopy = useNotifyCopy();
Expand Down Expand Up @@ -132,6 +134,13 @@ export default function BlockActions( {
},
async onPasteStyles() {
await pasteStyles( blocks );

// Need to reselect the block(s) in order for optional tool panel control changes to register.
clearSelectedBlock();
multiSelect(
blocks[ 0 ].clientId,
blocks[ blocks.length - 1 ].clientId
);
},
} );
}
13 changes: 11 additions & 2 deletions packages/block-editor/src/components/off-canvas-editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,18 @@ export const BLOCK_LIST_ITEM_HEIGHT = 36;
* @param {boolean} props.showBlockMovers Flag to enable block movers
* @param {boolean} props.isExpanded Flag to determine whether nested levels are expanded by default.
* @param {Object} props.LeafMoreMenu Optional more menu substitution.
* @param {string} props.description Optional accessible description for the tree grid component.
* @param {Object} ref Forwarded ref
*/
function OffCanvasEditor(
{ id, blocks, showBlockMovers = false, isExpanded = false, LeafMoreMenu },
{
id,
blocks,
showBlockMovers = false,
isExpanded = false,
LeafMoreMenu,
description = __( 'Block navigation structure' ),
},
ref
) {
const { clientIdsTree, draggedClientIds, selectedClientIds } =
Expand Down Expand Up @@ -208,7 +216,8 @@ function OffCanvasEditor(
onCollapseRow={ collapseRow }
onExpandRow={ expandRow }
onFocusRow={ focusRow }
applicationAriaLabel={ __( 'Block navigation structure' ) }
// eslint-disable-next-line jsx-a11y/aria-props
aria-description={ description }
>
<ListViewContext.Provider value={ contextValue }>
<ListViewBranch
Expand Down
130 changes: 67 additions & 63 deletions packages/block-library/src/avatar/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,67 +16,19 @@
function render_block_core_avatar( $attributes, $content, $block ) {
$size = isset( $attributes['size'] ) ? $attributes['size'] : 96;
$wrapper_attributes = get_block_wrapper_attributes();
$border_attributes = get_block_core_avatar_border_attributes( $attributes );

$image_styles = array();
// Class gets passed through `esc_attr` via `get_avatar`.
$image_classes = ! empty( $border_attributes['class'] )
? "wp-block-avatar__image {$border_attributes['class']}"
: 'wp-block-avatar__image';

// Add border width styles.
$has_border_width = ! empty( $attributes['style']['border']['width'] );

if ( $has_border_width ) {
$border_width = $attributes['style']['border']['width'];
$image_styles[] = sprintf( 'border-width: %s;', esc_attr( $border_width ) );
}

// Add border radius styles.
$has_border_radius = ! empty( $attributes['style']['border']['radius'] );

if ( $has_border_radius ) {
$border_radius = $attributes['style']['border']['radius'];

if ( is_array( $border_radius ) ) {
// Apply styles for individual corner border radii.
foreach ( $border_radius as $key => $value ) {
if ( null !== $value ) {
$name = _wp_to_kebab_case( $key );
// Add shared styles for individual border radii.
$border_style = sprintf(
'border-%s-radius: %s;',
esc_attr( $name ),
esc_attr( $value )
);
$image_styles[] = $border_style;
}
}
} else {
$border_style = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );
$image_styles[] = $border_style;
}
}

// Add border color styles.
$has_border_color = ! empty( $attributes['style']['border']['color'] );

if ( $has_border_color ) {
$border_color = $attributes['style']['border']['color'];
$image_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
}

// Add border style (solid, dashed, dotted ).
$has_border_style = ! empty( $attributes['style']['border']['style'] );

if ( $has_border_style ) {
$border_style = $attributes['style']['border']['style'];
$image_styles[] = sprintf( 'border-style: %s;', esc_attr( $border_style ) );
}

// Add border classes to the avatar image for both custom colors and palette colors.
$image_classes = '';
if ( $has_border_color || isset( $attributes['borderColor'] ) ) {
$image_classes .= 'has-border-color';
}
if ( isset( $attributes['borderColor'] ) ) {
$image_classes .= ' has-' . $attributes['borderColor'] . '-border-color';
}
// Unlike class, `get_avatar` doesn't filter the styles via `esc_attr`.
// The style engine does pass the border styles through
// `safecss_filter_attr` however.
$image_styles = ! empty( $border_attributes['style'] )
? sprintf( ' style="%s"', esc_attr( $border_attributes['style'] ) )
: '';

if ( ! isset( $block->context['commentId'] ) ) {
$author_id = isset( $attributes['userId'] ) ? $attributes['userId'] : get_post_field( 'post_author', $block->context['postId'] );
Expand All @@ -89,8 +41,8 @@ function render_block_core_avatar( $attributes, $content, $block ) {
'',
$alt,
array(
'extra_attr' => isset( $image_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $image_styles ) ) ) : '',
'class' => "wp-block-avatar__image $image_classes ",
'extra_attr' => $image_styles,
'class' => $image_classes,
)
);
if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) {
Expand All @@ -116,8 +68,8 @@ function render_block_core_avatar( $attributes, $content, $block ) {
'',
$alt,
array(
'extra_attr' => isset( $image_styles ) ? sprintf( ' style="%s"', safecss_filter_attr( implode( ' ', $image_styles ) ) ) : '',
'class' => "wp-block-avatar__image $image_classes",
'extra_attr' => $image_styles,
'class' => $image_classes,
)
);
if ( isset( $attributes['isLink'] ) && $attributes['isLink'] && isset( $comment->comment_author_url ) && '' !== $comment->comment_author_url ) {
Expand All @@ -132,6 +84,58 @@ function render_block_core_avatar( $attributes, $content, $block ) {
return sprintf( '<div %1s>%2s</div>', $wrapper_attributes, $avatar_block );
}

/**
* Generates class names and styles to apply the border support styles for
* the Avatar block.
*
* @param array $attributes The block attributes.
* @return array The border-related classnames and styles for the block.
*/
function get_block_core_avatar_border_attributes( $attributes ) {
$border_styles = array();
$sides = array( 'top', 'right', 'bottom', 'left' );

// Border radius.
if ( isset( $attributes['style']['border']['radius'] ) ) {
$border_styles['radius'] = $attributes['style']['border']['radius'];
}

// Border style.
if ( isset( $attributes['style']['border']['style'] ) ) {
$border_styles['style'] = $attributes['style']['border']['style'];
}

// Border width.
if ( isset( $attributes['style']['border']['width'] ) ) {
$border_styles['width'] = $attributes['style']['border']['width'];
}

// Border color.
$preset_color = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null;
$custom_color = _wp_array_get( $attributes, array( 'style', 'border', 'color' ), null );
$border_styles['color'] = $preset_color ? $preset_color : $custom_color;

// Individual border styles e.g. top, left etc.
foreach ( $sides as $side ) {
$border = _wp_array_get( $attributes, array( 'style', 'border', $side ), null );
$border_styles[ $side ] = array(
'color' => isset( $border['color'] ) ? $border['color'] : null,
'style' => isset( $border['style'] ) ? $border['style'] : null,
'width' => isset( $border['width'] ) ? $border['width'] : null,
);
}

$styles = wp_style_engine_get_styles( array( 'border' => $border_styles ) );
$attributes = array();
if ( ! empty( $styles['classnames'] ) ) {
$attributes['class'] = $styles['classnames'];
}
if ( ! empty( $styles['css'] ) ) {
$attributes['style'] = $styles['css'];
}
return $attributes;
}

/**
* Registers the `core/avatar` block on the server.
*/
Expand Down
Loading

0 comments on commit d078387

Please sign in to comment.