Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Preprocessors

Blocks_Width_Preprocessor::calculate_widthsprivateWC 1.0

Recursively calculate block widths based on layout and parent padding.

At the top level, root padding is zeroed out by preprocess() since it's distributed to individual blocks. Each block that received root padding from the Spacing_Preprocessor has its width reduced accordingly. For nested blocks, the parent block's own padding is subtracted as expected.

Method of the class: Blocks_Width_Preprocessor{}

No Hooks.

Returns

Array.

Usage

// private - for code of main (parent) class only
$result = $this->calculate_widths( $parsed_blocks, $layout, $styles, $variables_map ): array;
$parsed_blocks(array) (required)
Parsed blocks.
$layout(array) (required)
Layout settings.
$styles(array) (required)
Styles with padding from parent context.
$variables_map(array)
CSS variable names to resolved pixel values.
Default: array()

Blocks_Width_Preprocessor::calculate_widths() code WC 10.7.0

private function calculate_widths( array $parsed_blocks, array $layout, array $styles, array $variables_map = array() ): array {
	foreach ( $parsed_blocks as $key => $block ) {
		$layout_width = $this->parse_number_from_string_with_pixels( $layout['contentSize'] );
		$alignment    = $block['attrs']['align'] ?? null;
		// Subtract parent padding from block width if not full-width.
		if ( 'full' !== $alignment ) {
			$layout_width -= $this->parse_number_from_string_with_pixels( $styles['spacing']['padding']['left'] ?? '0px' );
			$layout_width -= $this->parse_number_from_string_with_pixels( $styles['spacing']['padding']['right'] ?? '0px' );
		}

		// Subtract root padding and container padding for blocks that will
		// receive them as CSS padding from Content_Renderer. This ensures
		// block widths fit inside the padding wrapper without overflow.
		if ( 'full' !== $alignment ) {
			$layout_width -= $this->parse_number_from_string_with_pixels( $block['email_attrs']['root-padding-left'] ?? '0px' );
			$layout_width -= $this->parse_number_from_string_with_pixels( $block['email_attrs']['root-padding-right'] ?? '0px' );
			// Container padding may be preset references (var:preset|spacing|20).
			$layout_width -= $this->parse_number_from_string_with_pixels( $this->resolve_preset_value( $block['email_attrs']['container-padding-left'] ?? '0px', $variables_map ) );
			$layout_width -= $this->parse_number_from_string_with_pixels( $this->resolve_preset_value( $block['email_attrs']['container-padding-right'] ?? '0px', $variables_map ) );
		}

		// Resolve block padding — may be preset references like var:preset|spacing|20.
		// When suppress-horizontal-padding is set, the block's horizontal padding
		// has been distributed per-block by the Spacing_Preprocessor. Zero it out
		// so children get the full available width.
		$suppress_h_padding  = ! empty( $block['email_attrs']['suppress-horizontal-padding'] );
		$block_padding_left  = $suppress_h_padding ? '0px' : $this->resolve_preset_value( $block['attrs']['style']['spacing']['padding']['left'] ?? '0px', $variables_map );
		$block_padding_right = $suppress_h_padding ? '0px' : $this->resolve_preset_value( $block['attrs']['style']['spacing']['padding']['right'] ?? '0px', $variables_map );

		$width_input = $block['attrs']['width'] ?? '100%';
		// Currently we support only % and px units in case only the number is provided we assume it's %
		// because editor saves percent values as a number.
		$width_input = is_numeric( $width_input ) ? "$width_input%" : $width_input;
		$width_input = is_string( $width_input ) ? $width_input : '100%';
		$width       = $this->convert_width_to_pixels( $width_input, $layout_width );

		if ( 'core/columns' === $block['blockName'] ) {
			// Calculate width of the columns based on the layout width and padding.
			$columns_width        = $layout_width;
			$columns_width       -= $this->parse_number_from_string_with_pixels( $block_padding_left );
			$columns_width       -= $this->parse_number_from_string_with_pixels( $block_padding_right );
			$border_width         = $block['attrs']['style']['border']['width'] ?? '0px';
			$columns_width       -= $this->parse_number_from_string_with_pixels( $block['attrs']['style']['border']['left']['width'] ?? $border_width );
			$columns_width       -= $this->parse_number_from_string_with_pixels( $block['attrs']['style']['border']['right']['width'] ?? $border_width );
			$block['innerBlocks'] = $this->add_missing_column_widths( $block['innerBlocks'], $columns_width, $variables_map );
		}

		// Copy layout styles and update width and padding with resolved values.
		$modified_layout                                = $layout;
		$modified_layout['contentSize']                 = "{$width}px";
		$modified_styles                                = $styles;
		$modified_styles['spacing']['padding']['left']  = $block_padding_left;
		$modified_styles['spacing']['padding']['right'] = $block_padding_right;

		$block['email_attrs']['width'] = "{$width}px";
		$block['innerBlocks']          = $this->calculate_widths( $block['innerBlocks'], $modified_layout, $modified_styles, $variables_map );
		$parsed_blocks[ $key ]         = $block;
	}
	return $parsed_blocks;
}