Block Editor: Update the WordPress Packages to the latest version.

This includes the packages that match the Gutenberg 9.2 Release.
It is going to be the last block-editor features update for WordPress 5.6.
It also updates the block-supports code base to the latest APIs.

Props isabel_brison, noisysocks, desrosj.
Fixes #51570.


git-svn-id: https://develop.svn.wordpress.org/trunk@49226 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Riad Benguella 2020-10-20 13:33:02 +00:00
parent a8d80fd4a7
commit 9fc20595b6
67 changed files with 2111 additions and 1148 deletions

1625
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -27,9 +27,9 @@
"devDependencies": {
"@wordpress/custom-templated-path-webpack-plugin": "1.7.0",
"@wordpress/dependency-extraction-webpack-plugin": "2.8.0",
"@wordpress/e2e-test-utils": "4.14.0",
"@wordpress/e2e-test-utils": "4.15.0",
"@wordpress/library-export-default-webpack-plugin": "1.9.0",
"@wordpress/scripts": "12.3.0",
"@wordpress/scripts": "12.4.0",
"autoprefixer": "9.6.2",
"chalk": "4.1.0",
"check-node-version": "4.0.1",
@ -80,52 +80,53 @@
"dependencies": {
"@babel/polyfill": "7.10.1",
"@wordpress/a11y": "2.13.0",
"@wordpress/annotations": "1.22.0",
"@wordpress/annotations": "1.23.0",
"@wordpress/api-fetch": "3.20.0",
"@wordpress/autop": "2.10.0",
"@wordpress/blob": "2.10.0",
"@wordpress/block-directory": "1.16.1",
"@wordpress/block-editor": "5.0.1",
"@wordpress/block-library": "2.25.1",
"@wordpress/blob": "2.11.0",
"@wordpress/block-directory": "1.17.0",
"@wordpress/block-editor": "5.1.0",
"@wordpress/block-library": "2.26.0",
"@wordpress/block-serialization-default-parser": "3.8.0",
"@wordpress/blocks": "6.23.0",
"@wordpress/components": "11.0.0",
"@wordpress/compose": "3.21.0",
"@wordpress/core-data": "2.23.0",
"@wordpress/data": "4.24.0",
"@wordpress/data-controls": "1.18.0",
"@wordpress/blocks": "6.24.0",
"@wordpress/components": "11.1.0",
"@wordpress/compose": "3.22.0",
"@wordpress/core-data": "2.24.0",
"@wordpress/data": "4.25.0",
"@wordpress/data-controls": "1.19.0",
"@wordpress/date": "3.12.0",
"@wordpress/deprecated": "2.10.0",
"@wordpress/dom": "2.15.0",
"@wordpress/dom-ready": "2.11.0",
"@wordpress/edit-post": "3.24.1",
"@wordpress/editor": "9.23.1",
"@wordpress/edit-post": "3.25.0",
"@wordpress/editor": "9.24.0",
"@wordpress/element": "2.18.0",
"@wordpress/escape-html": "1.10.0",
"@wordpress/format-library": "1.24.1",
"@wordpress/format-library": "1.25.0",
"@wordpress/hooks": "2.10.0",
"@wordpress/html-entities": "2.9.0",
"@wordpress/i18n": "3.16.0",
"@wordpress/icons": "2.7.0",
"@wordpress/icons": "2.8.0",
"@wordpress/is-shallow-equal": "2.3.0",
"@wordpress/keyboard-shortcuts": "1.11.0",
"@wordpress/keyboard-shortcuts": "1.12.0",
"@wordpress/keycodes": "2.16.0",
"@wordpress/list-reusable-blocks": "1.23.0",
"@wordpress/media-utils": "1.17.0",
"@wordpress/notices": "2.10.0",
"@wordpress/nux": "3.22.0",
"@wordpress/plugins": "2.22.0",
"@wordpress/primitives": "1.9.0",
"@wordpress/list-reusable-blocks": "1.24.0",
"@wordpress/media-utils": "1.18.0",
"@wordpress/notices": "2.11.0",
"@wordpress/nux": "3.23.0",
"@wordpress/plugins": "2.23.0",
"@wordpress/primitives": "1.10.0",
"@wordpress/priority-queue": "1.9.0",
"@wordpress/redux-routine": "3.12.0",
"@wordpress/rich-text": "3.22.0",
"@wordpress/server-side-render": "1.18.0",
"@wordpress/reusable-blocks": "1.0.0",
"@wordpress/rich-text": "3.23.0",
"@wordpress/server-side-render": "1.19.0",
"@wordpress/shortcode": "2.11.0",
"@wordpress/token-list": "1.13.0",
"@wordpress/url": "2.19.0",
"@wordpress/viewport": "2.23.0",
"@wordpress/viewport": "2.24.0",
"@wordpress/warning": "1.3.0",
"@wordpress/wordcount": "2.12.0",
"@wordpress/wordcount": "2.13.0",
"backbone": "1.4.0",
"clipboard": "2.0.6",
"core-js-url-browser": "3.6.4",

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,8 @@
/**
* Registers the align block attribute for block types that support it.
*
* @access private
*
* @param WP_Block_Type $block_type Block Type.
*/
function wp_register_alignment_support( $block_type ) {
@ -33,13 +35,15 @@ function wp_register_alignment_support( $block_type ) {
* Add CSS classes for block alignment to the incoming attributes array.
* This will be applied to the block markup in the front-end.
*
* @param array $attributes Comprehensive list of attributes to be applied.
* @param array $block_attributes Block attributes.
* @access private
*
* @param WP_Block_Type $block_type Block Type.
* @param array $block_attributes Block attributes.
*
* @return array Block alignment CSS classes and inline styles.
*/
function wp_apply_alignment_support( $attributes, $block_attributes, $block_type ) {
function wp_apply_alignment_support( $block_type, $block_attributes ) {
$attributes = array();
$has_align_support = false;
if ( property_exists( $block_type, 'supports' ) ) {
$has_align_support = wp_array_get( $block_type->supports, array( 'align' ), false );
@ -48,9 +52,18 @@ function wp_apply_alignment_support( $attributes, $block_attributes, $block_type
$has_block_alignment = array_key_exists( 'align', $block_attributes );
if ( $has_block_alignment ) {
$attributes['css_classes'][] = sprintf( 'align%s', $block_attributes['align'] );
$attributes['class'] = sprintf( 'align%s', $block_attributes['align'] );
}
}
return $attributes;
}
// Register the block support.
WP_Block_Supports::get_instance()->register(
'align',
array(
'register_attribute' => 'wp_register_alignment_support',
'apply' => 'wp_apply_alignment_support',
)
);

View File

@ -8,6 +8,8 @@
/**
* Registers the style and colors block attributes for block types that support it.
*
* @access private
*
* @param WP_Block_Type $block_type Block Type.
*/
function wp_register_colors_support( $block_type ) {
@ -53,18 +55,21 @@ function wp_register_colors_support( $block_type ) {
* Add CSS classes and inline styles for colors to the incoming attributes array.
* This will be applied to the block markup in the front-end.
*
* @param array $attributes Comprehensive list of attributes to be applied.
* @param array $block_attributes Block attributes.
* @access private
*
* @param WP_Block_Type $block_type Block type.
* @param array $block_attributes Block attributes.
*
* @return array Colors CSS classes and inline styles.
*/
function wp_apply_colors_support( $attributes, $block_attributes, $block_type ) {
function wp_apply_colors_support( $block_type, $block_attributes ) {
$color_support = wp_array_get( $block_type->supports, array( '__experimentalColor' ), false );
$has_text_colors_support = true === $color_support || ( is_array( $color_support ) && wp_array_get( $color_support, array( 'text' ), true ) );
$has_background_colors_support = true === $color_support || ( is_array( $color_support ) && wp_array_get( $color_support, array( 'background' ), true ) );
$has_link_colors_support = wp_array_get( $color_support, array( 'linkColor' ), false );
$has_gradients_support = wp_array_get( $color_support, array( 'gradients' ), false );
$classes = array();
$styles = array();
// Text Colors.
// Check support for text colors.
@ -74,13 +79,13 @@ function wp_apply_colors_support( $attributes, $block_attributes, $block_type )
// Apply required generic class.
if ( $has_custom_text_color || $has_named_text_color ) {
$attributes['css_classes'][] = 'has-text-color';
$classes[] = 'has-text-color';
}
// Apply color class or inline style.
if ( $has_named_text_color ) {
$attributes['css_classes'][] = sprintf( 'has-%s-color', $block_attributes['textColor'] );
$classes[] = sprintf( 'has-%s-color', $block_attributes['textColor'] );
} elseif ( $has_custom_text_color ) {
$attributes['inline_styles'][] = sprintf( 'color: %s;', $block_attributes['style']['color']['text'] );
$styles[] = sprintf( 'color: %s;', $block_attributes['style']['color']['text'] );
}
}
@ -89,15 +94,15 @@ function wp_apply_colors_support( $attributes, $block_attributes, $block_type )
$has_link_color = isset( $block_attributes['style']['color']['link'] );
// Apply required class and style.
if ( $has_link_color ) {
$attributes['css_classes'][] = 'has-link-color';
$classes[] = 'has-link-color';
// If link is a named color.
if ( strpos( $block_attributes['style']['color']['link'], 'var:preset|color|' ) !== false ) {
// Get the name from the string and add proper styles.
$index_to_splice = strrpos( $block_attributes['style']['color']['link'], '|' ) + 1;
$link_color_name = substr( $block_attributes['style']['color']['link'], $index_to_splice );
$attributes['inline_styles'][] = sprintf( '--wp--style--color--link:var(--wp--preset--color--%s);', $link_color_name );
$index_to_splice = strrpos( $block_attributes['style']['color']['link'], '|' ) + 1;
$link_color_name = substr( $block_attributes['style']['color']['link'], $index_to_splice );
$styles[] = sprintf( '--wp--style--color--link: var(--wp--preset--color--%s);', $link_color_name );
} else {
$attributes['inline_styles'][] = sprintf( '--wp--style--color--link: %s;', $block_attributes['style']['color']['link'] );
$styles[] = sprintf( '--wp--style--color--link: %s;', $block_attributes['style']['color']['link'] );
}
}
}
@ -109,13 +114,13 @@ function wp_apply_colors_support( $attributes, $block_attributes, $block_type )
// Apply required background class.
if ( $has_custom_background_color || $has_named_background_color ) {
$attributes['css_classes'][] = 'has-background';
$classes[] = 'has-background';
}
// Apply background color classes or styles.
if ( $has_named_background_color ) {
$attributes['css_classes'][] = sprintf( 'has-%s-background-color', $block_attributes['backgroundColor'] );
$classes[] = sprintf( 'has-%s-background-color', $block_attributes['backgroundColor'] );
} elseif ( $has_custom_background_color ) {
$attributes['inline_styles'][] = sprintf( 'background-color: %s;', $block_attributes['style']['color']['background'] );
$styles[] = sprintf( 'background-color: %s;', $block_attributes['style']['color']['background'] );
}
}
@ -125,15 +130,32 @@ function wp_apply_colors_support( $attributes, $block_attributes, $block_type )
$has_custom_gradient = isset( $block_attributes['style']['color']['gradient'] );
if ( $has_named_gradient || $has_custom_gradient ) {
$attributes['css_classes'][] = 'has-background';
$classes[] = 'has-background';
}
// Apply required background class.
if ( $has_named_gradient ) {
$attributes['css_classes'][] = sprintf( 'has-%s-gradient-background', $block_attributes['gradient'] );
$classes[] = sprintf( 'has-%s-gradient-background', $block_attributes['gradient'] );
} elseif ( $has_custom_gradient ) {
$attributes['inline_styles'][] = sprintf( 'background: %s;', $block_attributes['style']['color']['gradient'] );
$styles[] = sprintf( 'background: %s;', $block_attributes['style']['color']['gradient'] );
}
}
$attributes = array();
if ( ! empty( $classes ) ) {
$attributes['class'] = implode( ' ', $classes );
}
if ( ! empty( $styles ) ) {
$attributes['style'] = implode( ' ', $styles );
}
return $attributes;
}
// Register the block support.
WP_Block_Supports::get_instance()->register(
'colors',
array(
'register_attribute' => 'wp_register_colors_support',
'apply' => 'wp_apply_colors_support',
)
);

View File

@ -8,6 +8,8 @@
/**
* Registers the custom classname block attribute for block types that support it.
*
* @access private
*
* @param WP_Block_Type $block_type Block Type.
*/
function wp_register_custom_classname_support( $block_type ) {
@ -31,14 +33,16 @@ function wp_register_custom_classname_support( $block_type ) {
/**
* Add the custom classnames to the output.
*
* @param array $attributes Comprehensive list of attributes to be applied.
* @param array $block_attributes Block attributes.
* @access private
*
* @param WP_Block_Type $block_type Block Type.
* @param array $block_attributes Block attributes.
*
* @return array Block CSS classes and inline styles.
*/
function wp_apply_custom_classname_support( $attributes, $block_attributes, $block_type ) {
function wp_apply_custom_classname_support( $block_type, $block_attributes ) {
$has_custom_classname_support = true;
$attributes = array();
if ( property_exists( $block_type, 'supports' ) ) {
$has_custom_classname_support = wp_array_get( $block_type->supports, array( 'customClassName' ), true );
}
@ -46,9 +50,18 @@ function wp_apply_custom_classname_support( $attributes, $block_attributes, $blo
$has_custom_classnames = array_key_exists( 'className', $block_attributes );
if ( $has_custom_classnames ) {
$attributes['css_classes'][] = $block_attributes['className'];
$attributes['class'] = $block_attributes['className'];
}
}
return $attributes;
}
// Register the block support.
WP_Block_Supports::get_instance()->register(
'custom-classname',
array(
'register_attribute' => 'wp_register_custom_classname_support',
'apply' => 'wp_apply_custom_classname_support',
)
);

View File

@ -8,6 +8,8 @@
/**
* Get the generated classname from a given block name.
*
* @access private
*
* @param string $block_name Block Name.
* @return string Generated classname.
*/
@ -34,14 +36,16 @@ function wp_get_block_default_classname( $block_name ) {
/**
* Add the generated classnames to the output.
*
* @param array $attributes Comprehensive list of attributes to be applied.
* @param array $block_attributes Block attributes.
* @access private
*
* @param WP_Block_Type $block_type Block Type.
* @param array $block_attributes Block attributes.
*
* @return array Block CSS classes and inline styles.
*/
function wp_apply_generated_classname_support( $attributes, $block_attributes, $block_type ) {
function wp_apply_generated_classname_support( $block_type, $block_attributes ) {
$has_generated_classname_support = true;
$attributes = array();
if ( property_exists( $block_type, 'supports' ) ) {
$has_generated_classname_support = wp_array_get( $block_type->supports, array( 'className' ), true );
}
@ -49,9 +53,17 @@ function wp_apply_generated_classname_support( $attributes, $block_attributes, $
$block_classname = wp_get_block_default_classname( $block_type->name );
if ( $block_classname ) {
$attributes['css_classes'][] = $block_classname;
$attributes['class'] = $block_classname;
}
}
return $attributes;
}
// Register the block support.
WP_Block_Supports::get_instance()->register(
'generated-classname',
array(
'apply' => 'wp_apply_generated_classname_support',
)
);

View File

@ -1,137 +0,0 @@
<?php
/**
* Block support flags.
*
* @package WordPress
*/
// Require all the block supports mechanisms.
require __DIR__ . '/align.php';
require __DIR__ . '/colors.php';
require __DIR__ . '/custom-classname.php';
require __DIR__ . '/generated-classname.php';
require __DIR__ . '/typography.php';
/**
* Filter the registered blocks to apply the block supports attributes registration.
*/
function wp_register_block_supports() {
$block_registry = WP_Block_Type_Registry::get_instance();
$registered_block_types = $block_registry->get_all_registered();
// Ideally we need a hook to extend the block registration
// instead of mutating the block type.
foreach ( $registered_block_types as $block_type ) {
wp_register_alignment_support( $block_type );
wp_register_colors_support( $block_type );
wp_register_typography_support( $block_type );
wp_register_custom_classname_support( $block_type );
}
}
add_action( 'init', 'wp_register_block_supports', 21 );
/**
* Filters the frontend output of blocks and apply the block support flags transformations.
*
* @param string $block_content rendered block content.
* @param array $block block object.
* @return string filtered block content.
*/
function wp_apply_block_supports( $block_content, $block ) {
if ( ! isset( $block['attrs'] ) ) {
return $block_content;
}
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
// If no render_callback, assume styles have been previously handled.
if ( ! $block_type || ! $block_type->render_callback ) {
return $block_content;
}
$attributes = array();
$attributes = wp_apply_generated_classname_support( $attributes, $block['attrs'], $block_type );
$attributes = wp_apply_colors_support( $attributes, $block['attrs'], $block_type );
$attributes = wp_apply_typography_support( $attributes, $block['attrs'], $block_type );
$attributes = wp_apply_alignment_support( $attributes, $block['attrs'], $block_type );
$attributes = wp_apply_custom_classname_support( $attributes, $block['attrs'], $block_type );
if ( ! count( $attributes ) ) {
return $block_content;
}
$dom = new DOMDocument( '1.0', 'utf-8' );
// Suppress DOMDocument::loadHTML warnings from polluting the front-end.
$previous = libxml_use_internal_errors( true );
// We need to wrap the block in order to handle UTF-8 properly.
$wrapped_block_html =
'<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>'
. $block_content
. '</body></html>';
$success = $dom->loadHTML( $wrapped_block_html, LIBXML_HTML_NODEFDTD | LIBXML_COMPACT );
// Clear errors and reset the use_errors setting.
libxml_clear_errors();
libxml_use_internal_errors( $previous );
if ( ! $success ) {
return $block_content;
}
// Structure is like `<html><head/><body/></html>`, so body is the `lastChild` of our document.
$body_element = $dom->documentElement->lastChild; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$xpath = new DOMXPath( $dom );
$block_root = $xpath->query( './*', $body_element )[0];
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
if ( empty( $block_root ) ) {
return $block_content;
}
// Merge and dedupe new and existing classes and styles.
$current_classes = explode( ' ', trim( $block_root->getAttribute( 'class' ) ) );
$classes_to_add = array_key_exists( 'css_classes', $attributes ) ? $attributes['css_classes'] : array();
$new_classes = array_unique( array_filter( array_merge( $current_classes, $classes_to_add ) ) );
$current_styles = preg_split( '/\s*;\s*/', trim( $block_root->getAttribute( 'style' ) ) );
$styles_to_add = array_key_exists( 'inline_styles', $attributes ) ? $attributes['inline_styles'] : array();
$new_styles = array_unique( array_map( 'wp_normalize_css_rule', array_filter( array_merge( $current_styles, $styles_to_add ) ) ) );
// Apply new styles and classes.
if ( ! empty( $new_classes ) ) {
// `DOMElement::setAttribute` handles attribute value escaping.
$block_root->setAttribute( 'class', implode( ' ', $new_classes ) );
}
if ( ! empty( $new_styles ) ) {
// `DOMElement::setAttribute` handles attribute value escaping.
$block_root->setAttribute( 'style', implode( '; ', $new_styles ) . ';' );
}
// Avoid using `$dom->saveHtml( $node )` because the node results may not produce consistent
// whitespace for PHP < 7.3. Saving the root HTML `$dom->saveHtml()` prevents this behavior.
$full_html = $dom->saveHtml();
// Find the <body> open/close tags. The open tag needs to be adjusted so we get inside the tag
// and not the tag itself.
$start = strpos( $full_html, '<body>', 0 ) + strlen( '<body>' );
$end = strpos( $full_html, '</body>', $start );
return trim( substr( $full_html, $start, $end - $start ) );
}
add_filter( 'render_block', 'wp_apply_block_supports', 10, 2 );
/**
* Normalizes spacing in a string representing a CSS rule
*
* @example
* 'color :red;' becomes 'color:red'
*
* @param string $css_rule_string CSS rule.
* @return string Normalized CSS rule.
*/
function wp_normalize_css_rule( $css_rule_string ) {
return trim( implode( ': ', preg_split( '/\s*:\s*/', $css_rule_string, 2 ) ), ';' );
}

View File

@ -8,6 +8,8 @@
/**
* Registers the style and typography block attributes for block types that support it.
*
* @access private
*
* @param WP_Block_Type $block_type Block Type.
*/
function wp_register_typography_support( $block_type ) {
@ -16,11 +18,6 @@ function wp_register_typography_support( $block_type ) {
$has_font_size_support = wp_array_get( $block_type->supports, array( '__experimentalFontSize' ), false );
}
$has_font_style_support = false;
if ( property_exists( $block_type, 'supports' ) ) {
$has_font_style_support = wp_array_get( $block_type->supports, array( '__experimentalFontStyle' ), false );
}
$has_line_height_support = false;
if ( property_exists( $block_type, 'supports' ) ) {
$has_line_height_support = wp_array_get( $block_type->supports, array( '__experimentalLineHeight' ), false );
@ -30,7 +27,7 @@ function wp_register_typography_support( $block_type ) {
$block_type->attributes = array();
}
if ( ( $has_font_size_support || $has_font_style_support || $has_line_height_support ) && ! array_key_exists( 'style', $block_type->attributes ) ) {
if ( ( $has_font_size_support || $has_line_height_support ) && ! array_key_exists( 'style', $block_type->attributes ) ) {
$block_type->attributes['style'] = array(
'type' => 'object',
);
@ -47,26 +44,24 @@ function wp_register_typography_support( $block_type ) {
* Add CSS classes and inline styles for font sizes to the incoming attributes array.
* This will be applied to the block markup in the front-end.
*
* @param array $attributes Comprehensive list of attributes to be applied.
* @param array $block_attributes Block attributes.
* @access private
*
* @param WP_Block_Type $block_type Block type.
* @param array $block_attributes Block attributes.
*
* @return array Font size CSS classes and inline styles.
*/
function wp_apply_typography_support( $attributes, $block_attributes, $block_type ) {
function wp_apply_typography_support( $block_type, $block_attributes ) {
$has_font_size_support = false;
$classes = array();
$styles = array();
if ( property_exists( $block_type, 'supports' ) ) {
$has_font_size_support = wp_array_get( $block_type->supports, array( '__experimentalFontSize' ), false );
}
$has_font_style_support = false;
if ( property_exists( $block_type, 'supports' ) ) {
$has_font_style_support = wp_array_get( $block_type->supports, array( '__experimentalFontStyle' ), false );
$has_font_size_support = wp_array_get( $block_type->supports, array( 'fontSize' ), false );
}
$has_line_height_support = false;
if ( property_exists( $block_type, 'supports' ) ) {
$has_line_height_support = wp_array_get( $block_type->supports, array( '__experimentalLineHeight' ), false );
$has_line_height_support = wp_array_get( $block_type->supports, array( 'lineHeight' ), false );
}
// Font Size.
@ -76,35 +71,9 @@ function wp_apply_typography_support( $attributes, $block_attributes, $block_typ
// Apply required class or style.
if ( $has_named_font_size ) {
$attributes['css_classes'][] = sprintf( 'has-%s-font-size', $block_attributes['fontSize'] );
$classes[] = sprintf( 'has-%s-font-size', $block_attributes['fontSize'] );
} elseif ( $has_custom_font_size ) {
$attributes['inline_styles'][] = sprintf( 'font-size: %spx;', $block_attributes['style']['typography']['fontSize'] );
}
}
// Font Styles e.g. bold, italic, underline & strikethrough.
if ( $has_font_style_support ) {
$has_font_styles = isset( $block_attributes['style']['typography']['fontStyles'] );
// Apply required CSS classes.
if ( $has_font_styles ) {
$attributes['css_classes'][] = 'has-font-style';
// CSS class names chosen to be more explicit than generic `has-<something>-font-style`.
$font_style_classes = array(
'bold' => 'has-bold-font-weight',
'italic' => 'has-italic-font-style',
'underline' => 'has-underline-text-decoration',
'strikethrough' => 'has-strikethrough-text-decoration',
);
$style_selections = $block_attributes['style']['typography']['fontStyles'];
foreach ( $style_selections as $style => $turned_on ) {
if ( $turned_on ) {
$attributes['css_classes'][] = $font_style_classes[ $style ];
}
}
$styles[] = sprintf( 'font-size: %spx;', $block_attributes['style']['typography']['fontSize'] );
}
}
@ -113,9 +82,25 @@ function wp_apply_typography_support( $attributes, $block_attributes, $block_typ
$has_line_height = isset( $block_attributes['style']['typography']['lineHeight'] );
// Add the style (no classes for line-height).
if ( $has_line_height ) {
$attributes['inline_styles'][] = sprintf( 'line-height: %s;', $block_attributes['style']['typography']['lineHeight'] );
$styles[] = sprintf( 'line-height: %s;', $block_attributes['style']['typography']['lineHeight'] );
}
}
$attributes = array();
if ( ! empty( $classes ) ) {
$attributes['class'] = implode( ' ', $classes );
}
if ( ! empty( $styles ) ) {
$attributes['style'] = implode( ' ', $styles );
}
return $attributes;
}
WP_Block_Supports::get_instance()->register(
'typography',
array(
'register_attribute' => 'wp_register_typography_support',
'apply' => 'wp_apply_typography_support',
)
);

View File

@ -647,19 +647,33 @@ function _excerpt_render_inner_columns_blocks( $columns, $allowed_blocks ) {
return $output;
}
/**
* Block currently being parsed.
*
* @type array
*/
global $current_parsed_block;
$current_parsed_block = array(
'blockName' => null,
'attributes' => null,
);
/**
* Renders a single block into a HTML string.
*
* @since 5.0.0
*
* @global WP_Post $post The post to edit.
* @global WP_Query $wp_query WordPress Query object.
* @global array $current_parsed_block Block currently being parsed.
* @global WP_Post $post The post to edit.
* @global WP_Query $wp_query WordPress Query object.
* @global WP_Query $wp_query WordPress Query object.
*
* @param array $parsed_block A single parsed block object.
* @return string String of rendered HTML.
*/
function render_block( $parsed_block ) {
global $post, $wp_query;
global $post, $wp_query, $current_parsed_block;
/**
* Allows render_block() to be short-circuited, by returning a non-null value.
@ -674,6 +688,8 @@ function render_block( $parsed_block ) {
return $pre_render;
}
$current_parsed_block = $parsed_block;
$source_block = $parsed_block;
/**

View File

@ -97,9 +97,11 @@ function render_block_core_archives( $attributes ) {
);
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
return sprintf(
'<ul class="%1$s">%2$s</ul>',
$classnames,
'<ul %1$s>%2$s</ul>',
$wrapper_attributes,
$archives
);
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/archives",
"category": "widgets",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/audio",
"category": "media",
"attributes": {
@ -37,7 +38,6 @@
},
"supports": {
"anchor": true,
"align": true,
"lightBlockWrapper": true
"align": true
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/block",
"category": "reusable",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/button",
"category": "design",
"parent": [
@ -58,6 +59,6 @@
"align": true,
"alignWide": false,
"reusable": false,
"lightBlockWrapper": true
"__experimentalSelector": ".wp-block-button > a"
}
}

View File

@ -1,10 +1,10 @@
{
"apiVersion": 2,
"name": "core/buttons",
"category": "design",
"supports": {
"anchor": true,
"align": true,
"alignWide": false,
"lightBlockWrapper": true
"alignWide": false
}
}

View File

@ -31,8 +31,10 @@ function render_block_core_calendar( $attributes ) {
}
}
$output = sprintf(
'<div>%1$s</div>',
$wrapper_attributes = get_block_wrapper_attributes();
$output = sprintf(
'<div %1$s>%2$s</div>',
$wrapper_attributes,
get_calendar( true, false )
);

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/calendar",
"category": "widgets",
"attributes": {

View File

@ -28,7 +28,7 @@ function render_block_core_categories( $attributes ) {
$id = 'wp-block-categories-' . $block_id;
$args['id'] = $id;
$args['show_option_none'] = __( 'Select Category' );
$wrapper_markup = '<div class="%1$s">%2$s</div>';
$wrapper_markup = '<div %1$s>%2$s</div>';
$items_markup = wp_dropdown_categories( $args );
$type = 'dropdown';
@ -42,16 +42,16 @@ function render_block_core_categories( $attributes ) {
);
}
} else {
$wrapper_markup = '<ul class="%1$s">%2$s</ul>';
$wrapper_markup = '<ul %1$s>%2$s</ul>';
$items_markup = wp_list_categories( $args );
$type = 'list';
}
$class = "wp-block-categories-{$type}";
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => "wp-block-categories-{$type}" ) );
return sprintf(
$wrapper_markup,
esc_attr( $class ),
$wrapper_attributes,
$items_markup
);
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/categories",
"category": "widgets",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/freeform",
"category": "text",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/code",
"category": "text",
"attributes": {
@ -9,7 +10,6 @@
}
},
"supports": {
"anchor": true,
"lightBlockWrapper": true
"anchor": true
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/column",
"category": "text",
"parent": [
@ -9,15 +10,15 @@
"type": "string"
},
"width": {
"type": "number",
"min": 0,
"max": 100
"type": "string"
},
"templateLock": {
"type": "string"
}
},
"supports": {
"anchor": true,
"reusable": false,
"html": false,
"lightBlockWrapper": true
"html": false
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/columns",
"category": "design",
"attributes": {
@ -13,10 +14,9 @@
"full"
],
"html": false,
"lightBlockWrapper": true,
"__experimentalColor": {
"color": {
"gradients": true,
"linkColor": true
"link": true
}
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/embed",
"category": "embed",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/file",
"category": "media",
"attributes": {

View File

@ -1,10 +1,14 @@
{
"apiVersion": 2,
"name": "core/group",
"category": "design",
"attributes": {
"tagName": {
"type": "string",
"default": "div"
},
"templateLock": {
"type": "string"
}
},
"supports": {
@ -14,11 +18,12 @@
],
"anchor": true,
"html": false,
"lightBlockWrapper": true,
"__experimentalColor": {
"color": {
"gradients": true,
"linkColor": true
"link": true
},
"__experimentalPadding": true
"spacing": {
"padding": true
}
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/heading",
"category": "text",
"attributes": {
@ -20,14 +21,14 @@
}
},
"supports": {
"align": [ "wide", "full" ],
"anchor": true,
"className": false,
"lightBlockWrapper": true,
"__experimentalColor": {
"linkColor": true
"color": {
"link": true
},
"__experimentalFontSize": true,
"__experimentalLineHeight": true,
"fontSize": true,
"lineHeight": true,
"__experimentalSelector": {
"core/heading/h1": "h1",
"core/heading/h2": "h2",

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/html",
"category": "widgets",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/image",
"category": "media",
"attributes": {
@ -70,7 +71,6 @@
}
},
"supports": {
"anchor": true,
"lightBlockWrapper": true
"anchor": true
}
}

View File

@ -129,15 +129,15 @@ function render_block_core_latest_comments( $attributes = array() ) {
if ( empty( $comments ) ) {
$classnames[] = 'no-comments';
}
$class = esc_attr( implode( ' ', $classnames ) );
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) );
return ! empty( $comments ) ? sprintf(
'<ol class="%1$s">%2$s</ol>',
$class,
'<ol %1$s>%2$s</ol>',
$wrapper_attributes,
$list_items_markup
) : sprintf(
'<div class="%1$s">%2$s</div>',
$class,
'<div %1$s>%2$s</div>',
$wrapper_attributes,
__( 'No comments to show.' )
);
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/latest-comments",
"category": "widgets",
"attributes": {

View File

@ -171,9 +171,11 @@ function render_block_core_latest_posts( $attributes ) {
$class .= ' has-author';
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $class ) );
return sprintf(
'<ul class="%1$s">%2$s</ul>',
esc_attr( $class ),
'<ul %1$s>%2$s</ul>',
$wrapper_attributes,
$list_items_markup
);
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/list",
"category": "text",
"attributes": {
@ -27,10 +28,9 @@
"supports": {
"anchor": true,
"className": false,
"__experimentalColor": {
"color": {
"gradients": true
},
"__unstablePasteTextInline": true,
"lightBlockWrapper": true
"__unstablePasteTextInline": true
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/media-text",
"category": "media",
"attributes": {
@ -84,10 +85,9 @@
"anchor": true,
"align": [ "wide", "full" ],
"html": false,
"lightBlockWrapper": true,
"__experimentalColor": {
"color": {
"gradients": true,
"linkColor": true
"link": true
}
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/missing",
"category": "text",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/more",
"category": "design",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/nextpage",
"category": "design",
"parent": [ "core/post-content" ],

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/paragraph",
"category": "text",
"attributes": {
@ -29,12 +30,11 @@
"supports": {
"anchor": true,
"className": false,
"lightBlockWrapper": true,
"__experimentalColor": {
"linkColor": true
"color": {
"link": true
},
"__experimentalFontSize": true,
"__experimentalLineHeight": true,
"fontSize": true,
"lineHeight": true,
"__experimentalSelector": "p",
"__unstablePasteTextInline": true
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/preformatted",
"category": "text",
"attributes": {
@ -11,7 +12,6 @@
}
},
"supports": {
"anchor": true,
"lightBlockWrapper": true
"anchor": true
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/pullquote",
"category": "text",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/quote",
"category": "text",
"attributes": {
@ -20,7 +21,6 @@
}
},
"supports": {
"anchor": true,
"lightBlockWrapper": true
"anchor": true
}
}

View File

@ -87,8 +87,9 @@ function render_block_core_rss( $attributes ) {
if ( isset( $attributes['columns'] ) && 'grid' === $attributes['blockLayout'] ) {
$classnames[] = 'columns-' . $attributes['columns'];
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classnames ) ) );
return sprintf( '<ul class="%s">%s</ul>', esc_attr( implode( ' ', $classnames ) ), $list_items );
return sprintf( '<ul %s>%s</ul>', $wrapper_attributes, $list_items );
}
/**

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/rss",
"category": "widgets",
"attributes": {

View File

@ -65,20 +65,22 @@ function render_block_core_search( $attributes ) {
if ( $show_button ) {
$button_internal_markup = '';
$button_classes = '';
if ( ! $use_icon_button ) {
if ( ! empty( $attributes['buttonText'] ) ) {
$button_internal_markup = $attributes['buttonText'];
}
} else {
$button_classes .= 'has-icon';
$button_internal_markup =
'<svg id="search-icon" class="search-icon" viewBox="0 0 24 24">
'<svg id="search-icon" class="search-icon" viewBox="0 0 24 24" width="24" height="24">
<path d="M13.5 6C10.5 6 8 8.5 8 11.5c0 1.1.3 2.1.9 3l-3.4 3 1 1.1 3.4-2.9c1 .9 2.2 1.4 3.6 1.4 3 0 5.5-2.5 5.5-5.5C19 8.5 16.5 6 13.5 6zm0 9.5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"></path>
</svg>';
}
$button_markup = sprintf(
'<button type="submit" class="wp-block-search__button">%s</button>',
'<button type="submit"class="wp-block-search__button ' . $button_classes . '">%s</button>',
$button_internal_markup
);
}
@ -89,16 +91,17 @@ function render_block_core_search( $attributes ) {
}
}
$field_markup = sprintf(
$field_markup = sprintf(
'<div class="wp-block-search__inside-wrapper"%s>%s</div>',
$width_styles,
$input_markup . $button_markup
);
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
return sprintf(
'<form role="search" method="get" action="%s" class="%s">%s</form>',
'<form role="search" method="get" action="%s" %s>%s</form>',
esc_url( home_url( '/' ) ),
$classnames,
$wrapper_attributes,
$label_markup . $field_markup
);
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/search",
"category": "widgets",
"attributes": {
@ -6,7 +7,7 @@
"type": "string"
},
"showLabel": {
"type": "bool",
"type": "boolean",
"default": true
},
"placeholder": {
@ -27,13 +28,12 @@
"default": "button-outside"
},
"buttonUseIcon": {
"type": "bool",
"type": "boolean",
"default": false
}
},
"supports": {
"align": [ "left", "center", "right" ],
"html": false,
"lightBlockWrapper": true
"html": false
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/separator",
"category": "design",
"attributes": {
@ -10,6 +11,7 @@
}
},
"supports": {
"anchor": true
"anchor": true,
"align": ["center","wide","full"]
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/shortcode",
"category": "widgets",
"attributes": {

View File

@ -32,8 +32,10 @@ function render_block_core_social_link( $attributes, $content, $block ) {
$attribute = 'rel="noopener nofollow" target="_blank"';
}
$icon = block_core_social_link_get_icon( $service );
return '<li class="wp-social-link wp-social-link-' . esc_attr( $service ) . esc_attr( $class_name ) . '"><a href="' . esc_url( $url ) . '" aria-label="' . esc_attr( $label ) . '" ' . $attribute . '> ' . $icon . '</a></li>';
$icon = block_core_social_link_get_icon( $service );
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => 'wp-social-link wp-social-link-' . $service . $class_name ) );
return '<li ' . $wrapper_attributes . '><a href="' . esc_url( $url ) . '" aria-label="' . esc_attr( $label ) . '" ' . $attribute . '> ' . $icon . '</a></li>';
}
/**

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/social-link",
"category": "widgets",
"parent": [
@ -20,7 +21,6 @@
],
"supports": {
"reusable": false,
"html": false,
"lightBlockWrapper": true
"html": false
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/social-links",
"category": "widgets",
"attributes": {
@ -16,7 +17,6 @@
"center",
"right"
],
"lightBlockWrapper": true,
"anchor": true
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/spacer",
"category": "design",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/subhead",
"category": "text",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/table",
"category": "text",
"attributes": {
@ -123,6 +124,7 @@
},
"supports": {
"anchor": true,
"align": true
"align": true,
"__experimentalSelector": ".wp-block-button > table"
}
}

View File

@ -31,8 +31,11 @@ function render_block_core_tag_cloud( $attributes ) {
);
}
$wrapper_attributes = get_block_wrapper_attributes();
return sprintf(
'<p>%1$s</p>',
'<p %1$s>%2$s</p>',
$wrapper_attributes,
$tag_cloud
);
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/tag-cloud",
"category": "widgets",
"attributes": {

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/text-columns",
"icon": "columns",
"category": "design",

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/verse",
"category": "text",
"attributes": {
@ -14,7 +15,6 @@
}
},
"supports": {
"anchor": true,
"lightBlockWrapper": true
"anchor": true
}
}

View File

@ -1,4 +1,5 @@
{
"apiVersion": 2,
"name": "core/video",
"category": "media",
"attributes": {
@ -59,11 +60,17 @@
"source": "attribute",
"selector": "video",
"attribute": "playsinline"
},
"tracks": {
"type": "array",
"items": {
"type": "object"
},
"default": []
}
},
"supports": {
"anchor": true,
"align": true,
"lightBlockWrapper": true
"align": true
}
}

View File

@ -0,0 +1,211 @@
<?php
/**
* Block support flags.
*
* @package WordPress
*
* @since 5.6.0
*/
/**
* Class encapsulating and implementing Block Supports.
*
* @since 5.6.0
*
* @access private
*/
class WP_Block_Supports {
/**
* Config.
*
* @var array
*/
private $block_supports = array();
/**
* Container for the main instance of the class.
*
* @var WP_Block_Supports|null
*/
private static $instance = null;
/**
* Utility method to retrieve the main instance of the class.
*
* The instance will be created if it does not exist yet.
*
* @since 5.6.0
*
* @return WP_Block_Supports The main instance.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Initializes the block supports. It registes the block supports block attributes.
*
* @since 5.6.0
*/
public static function init() {
$instance = self::get_instance();
$instance->register_attributes();
}
/**
* Registers a block support.
*
* @since 5.6.0
*
* @param string $block_support_name Block support name.
* @param array $block_support_config Array containing the properties of the block support.
*/
public function register( $block_support_name, $block_support_config ) {
$this->block_supports[ $block_support_name ] = array_merge(
$block_support_config,
array( 'name' => $block_support_name )
);
}
/**
* Generates an array of HTML attributes, such as classes, by applying to
* the given block all of the features that the block supports.
*
* @since 5.6.0
*
* @param array $parsed_block Block as parsed from content.
* @return array Array of HTML attributes.
*/
public function apply_block_supports( $parsed_block ) {
$block_attributes = $parsed_block['attrs'];
$block_type = WP_Block_Type_Registry::get_instance()->get_registered(
$parsed_block['blockName']
);
// If no render_callback, assume styles have been previously handled.
if ( ! $block_type || empty( $block_type ) ) {
return array();
}
$output = array();
foreach ( $this->block_supports as $name => $block_support_config ) {
if ( ! isset( $block_support_config['apply'] ) ) {
continue;
}
$new_attributes = call_user_func(
$block_support_config['apply'],
$block_type,
$block_attributes
);
if ( ! empty( $new_attributes ) ) {
foreach ( $new_attributes as $attribute_name => $attribute_value ) {
if ( empty( $output[ $attribute_name ] ) ) {
$output[ $attribute_name ] = $attribute_value;
} else {
$output[ $attribute_name ] .= " $attribute_value";
}
}
}
}
return $output;
}
/**
* Registers the block attributes required by the different block supports.
*
* @since 5.6.0
*/
private function register_attributes() {
$block_registry = WP_Block_Type_Registry::get_instance();
$registered_block_types = $block_registry->get_all_registered();
foreach ( $registered_block_types as $block_type ) {
if ( ! property_exists( $block_type, 'supports' ) ) {
continue;
}
if ( ! $block_type->attributes ) {
$block_type->attributes = array();
}
foreach ( $this->block_supports as $name => $block_support_config ) {
if ( ! isset( $block_support_config['register_attribute'] ) ) {
continue;
}
call_user_func(
$block_support_config['register_attribute'],
$block_type
);
}
}
}
}
/**
* Generates a string of attributes by applying to the current block being
* rendered all of the features that the block supports.
*
* @since 5.6.0
*
* @global array $current_parsed_block Block currently being parsed.
*
* @param array $extra_attributes Optional. Extra attributes to render on the block wrapper.
*
* @return string String of HTML classes.
*/
function get_block_wrapper_attributes( $extra_attributes = array() ) {
global $current_parsed_block;
$new_attributes = WP_Block_Supports::get_instance()->apply_block_supports( $current_parsed_block );
if ( empty( $new_attributes ) && empty( $extra_attributes ) ) {
return '';
}
// This is hardcoded on purpose.
// We only support a fixed list of attributes.
$attributes_to_merge = array( 'style', 'class' );
$attributes = array();
foreach ( $attributes_to_merge as $attribute_name ) {
if ( empty( $new_attributes[ $attribute_name ] ) && empty( $extra_attributes[ $attribute_name ] ) ) {
continue;
}
if ( empty( $new_attributes[ $attribute_name ] ) ) {
$attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ];
continue;
}
if ( empty( $extra_attributes[ $attribute_name ] ) ) {
$attributes[ $attribute_name ] = $new_attributes[ $attribute_name ];
continue;
}
$attributes[ $attribute_name ] = $extra_attributes[ $attribute_name ] . ' ' . $new_attributes[ $attribute_name ];
}
foreach ( $extra_attributes as $attribute_name => $value ) {
if ( ! in_array( $attribute_name, $attributes_to_merge, true ) ) {
$attributes[ $attribute_name ] = $value;
}
}
if ( empty( $attributes ) ) {
return '';
}
$normalized_attributes = array();
foreach ( $attributes as $key => $value ) {
$normalized_attributes[] = $key . '="' . esc_attr( $value ) . '"';
}
return implode( ' ', $normalized_attributes );
}

View File

@ -192,7 +192,7 @@ class WP_Block {
* @return string Rendered block output.
*/
public function render( $options = array() ) {
global $post;
global $post, $current_parsed_block;
$options = wp_parse_args(
$options,
array(
@ -206,9 +206,14 @@ class WP_Block {
if ( ! $options['dynamic'] || empty( $this->block_type->skip_inner_blocks ) ) {
$index = 0;
foreach ( $this->inner_content as $chunk ) {
$block_content .= is_string( $chunk ) ?
$chunk :
$this->inner_blocks[ $index++ ]->render();
if ( is_string( $chunk ) ) {
$block_content .= $chunk;
} else {
$parent_parsed_block = $current_parsed_block;
$current_parsed_block = $this->inner_blocks[ $index ]->parsed_block;
$block_content .= $this->inner_blocks[ $index++ ]->render();
$current_parsed_block = $parent_parsed_block;
}
}
}

View File

@ -305,6 +305,7 @@ add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 );
add_action( 'wp_print_footer_scripts', '_wp_footer_scripts' );
add_action( 'init', '_register_core_block_patterns_and_categories' );
add_action( 'init', 'check_theme_switched', 99 );
add_action( 'init', array( 'WP_Block_Supports', 'init' ), 22 );
add_action( 'after_switch_theme', '_wp_menus_changed' );
add_action( 'after_switch_theme', '_wp_sidebars_changed' );
add_action( 'wp_print_styles', 'print_emoji_styles' );

View File

@ -292,7 +292,12 @@ require ABSPATH . WPINC . '/class-wp-block-parser.php';
require ABSPATH . WPINC . '/blocks.php';
require ABSPATH . WPINC . '/blocks/index.php';
require ABSPATH . WPINC . '/block-patterns.php';
require ABSPATH . WPINC . '/block-supports/index.php';
require ABSPATH . WPINC . '/class-wp-block-supports.php';
require ABSPATH . WPINC . '/block-supports/align.php';
require ABSPATH . WPINC . '/block-supports/colors.php';
require ABSPATH . WPINC . '/block-supports/custom-classname.php';
require ABSPATH . WPINC . '/block-supports/generated-classname.php';
require ABSPATH . WPINC . '/block-supports/typography.php';
$GLOBALS['wp_embed'] = new WP_Embed();

View File

@ -1 +1 @@
<div class="wp-block-archives-list wp-block-archives">No archives to show.</div>
<div class=" wp-block-archives-list">No archives to show.</div>

View File

@ -1 +1 @@
<div class="wp-block-archives-list wp-block-archives">No archives to show.</div>
<div class=" wp-block-archives-list">No archives to show.</div>

View File

@ -171,6 +171,7 @@ require __DIR__ . '/testcase-rest-controller.php';
require __DIR__ . '/testcase-rest-post-type-controller.php';
require __DIR__ . '/testcase-xmlrpc.php';
require __DIR__ . '/testcase-ajax.php';
require __DIR__ . '/testcase-block-supports.php';
require __DIR__ . '/testcase-canonical.php';
require __DIR__ . '/testcase-xml.php';
require __DIR__ . '/exceptions.php';

View File

@ -0,0 +1,777 @@
<?php
/**
* Test block supported styles.
*
* @package WordPress
* @subpackage UnitTests
* @since 5.6.0
*/
class Block_Supported_Styles_Test extends WP_UnitTestCase {
/**
* Registered block names.
*
* @var string[]
*/
private $registered_block_names = array();
/**
* Sets up each test method.
*/
public function setUp() {
parent::setUp();
}
/**
* Tear down each test method.
*/
public function tearDown() {
parent::tearDown();
while ( ! empty( $this->registered_block_names ) ) {
$block_name = array_pop( $this->registered_block_names );
unregister_block_type( $block_name );
}
}
/**
* Registers a block type.
*
* @param string|WP_Block_Type $name Block type name including namespace, or alternatively a
* complete WP_Block_Type instance. In case a WP_Block_Type
* is provided, the $args parameter will be ignored.
* @param array $args {
* Optional. Array of block type arguments. Any arguments may be defined, however the
* ones described below are supported by default. Default empty array.
*
* @type callable $render_callback Callback used to render blocks of this block type.
* }
*/
protected function register_block_type( $name, $args ) {
register_block_type( $name, $args );
$this->registered_block_names[] = $name;
}
/**
* Retrieves attribute such as 'class' or 'style' from the rendered block string.
*
* @param string $attribute Name of attribute to get.
* @param string $block String of rendered block to check.
*/
private function get_attribute_from_block( $attribute, $block ) {
$start_index = strpos( $block, $attribute . '="' ) + strlen( $attribute ) + 2;
$split_arr = substr( $block, $start_index );
$end_index = strpos( $split_arr, '"' );
return substr( $split_arr, 0, $end_index );
}
/**
* Retrieves block content from the rendered block string
* (i.e. what's wrapped by the block wrapper `<div />`).
*
* @param string $block String of rendered block to check.
*/
private function get_content_from_block( $block ) {
$start_index = strpos( $block, '>' ) + 1; // First occurrence of '>'.
$split_arr = substr( $block, $start_index );
$end_index = strrpos( $split_arr, '<' ); // Last occurrence of '<'.
return substr( $split_arr, 0, $end_index ); // String between first '>' and last '<'.
}
/**
* Block content to test with (i.e. what's wrapped by the block wrapper `<div />`).
*
* @var string
*/
const BLOCK_CONTENT = '
<p data-image-description="&lt;p&gt;Test!&lt;/p&gt;">Test</p>
<p>äöü</p>
<p>ß</p>
<p>系の家庭に</p>
<p>Example &lt;p&gt;Test!&lt;/p&gt;</p>
';
/**
* Returns the rendered output for the current block.
*
* @param array $block Block to render.
*/
private function render_example_block( $block ) {
global $current_parsed_block;
$current_parsed_block = $block;
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => 'foo-bar-class',
'style' => 'test: style;',
)
);
return '<div ' . $wrapper_attributes . '>' . self::BLOCK_CONTENT . '</div>';
}
/**
* Runs assertions that the rendered output has expected class/style attrs.
*
* @param array $block Block to render.
* @param string $expected_classes Expected output class attr string.
* @param string $expected_styles Expected output styles attr string.
*/
private function assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ) {
$styled_block = $this->render_example_block( $block );
$class_list = $this->get_attribute_from_block( 'class', $styled_block );
$style_list = $this->get_attribute_from_block( 'style', $styled_block );
$this->assertEquals( $expected_classes, $class_list );
$this->assertEquals( $expected_styles, $style_list );
}
/**
* Runs assertions that the rendered output has expected content and class/style attrs.
*
* @param array $block Block to render.
* @param string $expected_classes Expected output class attr string.
* @param string $expected_styles Expected output styles attr string.
*/
private function assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles ) {
$styled_block = $this->render_example_block( $block );
// Ensure blocks to not add extra whitespace.
$this->assertEquals( $styled_block, trim( $styled_block ) );
$content = $this->get_content_from_block( $styled_block );
$class_list = $this->get_attribute_from_block( 'class', $styled_block );
$style_list = $this->get_attribute_from_block( 'style', $styled_block );
$this->assertEquals( self::BLOCK_CONTENT, $content );
$this->assertEqualSets(
explode( ' ', $expected_classes ),
explode( ' ', $class_list )
);
$this->assertEquals(
array_map( 'trim', explode( ';', $expected_styles ) ),
array_map( 'trim', explode( ';', $style_list ) )
);
}
/**
* Tests color support for named color support for named colors.
*/
function test_named_color_support() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'color' => true,
),
'render_callback' => true,
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'textColor' => 'red',
'backgroundColor' => 'black',
// The following should not be applied (subcatagories of color support).
'gradient' => 'some-gradient',
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example has-text-color has-red-color has-background has-black-background-color';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests color support for custom colors.
*/
function test_custom_color_support() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'color' => true,
),
'render_callback' => true,
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'style' => array(
'color' => array(
'text' => '#000',
'background' => '#fff',
// The following should not be applied (subcatagories of color support).
'gradient' => 'some-gradient',
'style' => array( 'color' => array( 'link' => '#fff' ) ),
),
),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_styles = 'test: style; color: #000; background-color: #fff;';
$expected_classes = 'foo-bar-class wp-block-example has-text-color has-background';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests link color support for named colors.
*/
function test_named_link_color_support() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'color' => array(
'link' => true,
),
),
'render_callback' => true,
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'style' => array( 'color' => array( 'link' => 'var:preset|color|red' ) ),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example has-link-color';
$expected_styles = 'test: style; --wp--style--color--link: var(--wp--preset--color--red);';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests link color support for custom colors.
*/
function test_custom_link_color_support() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'color' => array(
'link' => true,
),
),
'render_callback' => true,
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'style' => array( 'color' => array( 'link' => '#fff' ) ),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example has-link-color';
$expected_styles = 'test: style; --wp--style--color--link: #fff;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests gradient color support for named gradients.
*/
function test_named_gradient_support() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'color' => array(
'gradients' => true,
),
),
'render_callback' => true,
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'gradient' => 'red',
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example has-background has-red-gradient-background';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests gradient color support for custom gradients.
*/
function test_custom_gradient_support() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'color' => array(
'gradients' => true,
),
),
'render_callback' => true,
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'style' => array( 'color' => array( 'gradient' => 'some-gradient-style' ) ),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example has-background';
$expected_styles = 'test: style; background: some-gradient-style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests that style attributes for colors are not applied without the support flag.
*/
function test_color_unsupported() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(),
'render_callback' => true,
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'textColor' => 'red',
'backgroundColor' => 'black',
'style' => array(
'color' => array(
'text' => '#000',
'background' => '#fff',
'link' => '#ggg',
'gradient' => 'some-gradient',
),
),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests support for named font sizes.
*/
function test_named_font_size() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'fontSize' => true,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'fontSize' => 'large',
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example has-large-font-size';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests support for custom font sizes.
*/
function test_custom_font_size() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'fontSize' => true,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'style' => array( 'typography' => array( 'fontSize' => '10' ) ),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example';
$expected_styles = 'test: style; font-size: 10px;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests that font size attributes are not applied without support flag.
*/
function test_font_size_unsupported() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'fontSize' => 'large',
'style' => array( 'typography' => array( 'fontSize' => '10' ) ),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests line height support.
*/
function test_line_height() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'lineHeight' => true,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'style' => array( 'typography' => array( 'lineHeight' => '10' ) ),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example';
$expected_styles = 'test: style; line-height: 10;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests line height not applied without support flag.
*/
function test_line_height_unsupported() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'style' => array( 'typography' => array( 'lineHeight' => '10' ) ),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests support for block alignment.
*/
function test_block_alignment() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'align' => true,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'align' => 'wide',
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example alignwide';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests block alignment requires support to be added.
*/
function test_block_alignment_unsupported() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'align' => 'wide',
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example';
$expected_styles = 'test: style;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests all support flags together to ensure they work together as expected.
*/
function test_all_supported() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'color' => array(
'gradients' => true,
'link' => true,
),
'fontSize' => true,
'lineHeight' => true,
'align' => true,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'align' => 'wide',
'style' => array(
'color' => array(
'text' => '#000',
'background' => '#fff',
'style' => array( 'color' => array( 'link' => '#fff' ) ),
),
'typography' => array(
'lineHeight' => '20',
'fontSize' => '10',
),
),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example has-text-color has-background alignwide';
$expected_styles = 'test: style; color: #000; background-color: #fff; font-size: 10px; line-height: 20;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests that only styles for the supported flag are added.
* Verify one support enabled does not imply multiple supports enabled.
*/
function test_one_supported() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'fontSize' => true,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'align' => 'wide',
'style' => array(
'color' => array(
'text' => '#000',
'background' => '#fff',
'gradient' => 'some-gradient',
'style' => array( 'color' => array( 'link' => '#fff' ) ),
),
'typography' => array(
'lineHeight' => '20',
'fontSize' => '10',
),
),
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_classes = 'foo-bar-class wp-block-example';
$expected_styles = 'test: style; font-size: 10px;';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests custom classname server-side block support.
*/
function test_custom_classnames_support() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'className' => 'my-custom-classname',
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_styles = 'test: style;';
$expected_classes = 'foo-bar-class wp-block-example my-custom-classname';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests custom classname server-side block support opt-out.
*/
function test_custom_classnames_support_opt_out() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'customClassName' => false,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(
'className' => 'my-custom-classname',
),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_styles = 'test: style;';
$expected_classes = 'foo-bar-class wp-block-example';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Tests generated classname server-side block support opt-out.
*/
function test_generatted_classnames_support_opt_out() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(
'className' => false,
),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
$expected_styles = 'test: style;';
$expected_classes = 'foo-bar-class';
$this->assert_content_and_styles_and_classes_match( $block, $expected_classes, $expected_styles );
}
/**
* Ensures libxml_internal_errors is being used instead of @ warning suppression
*/
public function test_render_block_suppresses_warnings_without_at_suppression() {
$block_type_settings = array(
'attributes' => array(),
'supports' => array(),
);
$this->register_block_type( 'core/example', $block_type_settings );
$block = array(
'blockName' => 'core/example',
'attrs' => array(),
'innerBlock' => array(),
'innerContent' => array(),
'innerHTML' => array(),
);
// Custom error handler's see Warnings even if they are suppressed by the @ symbol.
$errors = array();
set_error_handler(
function ( $errno = 0, $errstr = '' ) use ( &$errors ) {
$errors[] = $errstr;
return false;
}
);
// HTML5 elements like <time> are not supported by the DOMDocument parser used by the block supports feature.
// This specific example is emitted by the "Display post date" setting in the latest-posts block.
apply_filters( 'render_block', '<div><time datetime="2020-06-18T04:01:43+10:00" class="wp-block-latest-posts__post-date">June 18, 2020</time></div>', $block );
restore_error_handler();
$this->assertEmpty( $errors, 'Libxml errors should be dropped.' );
}
}