From 214b8ad5e1e92ab68631cb903d3115dacad34652 Mon Sep 17 00:00:00 2001 From: noruzzamans Date: Sat, 12 Sep 2026 10:03:12 +0600 Subject: [PATCH] Block Supports: Allow CSS custom properties in block gap sanitization Ensures gutenberg_sanitize_block_gap_value() accepts valid CSS custom property references such as var(--wp--preset--spacing--*). This fixes an issue where Grid layout calculations fell back to 0.5em when using global theme.json blockGap presets on capped columns. Fixes #82747. --- lib/block-supports/layout.php | 5 +++ phpunit/block-supports/layout-test.php | 48 ++++++++++++++++++++------ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index a2448b6f7abdce..7e8b04f6897181 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -315,6 +315,11 @@ function gutenberg_sanitize_block_gap_value( $gap_value ) { return null; } + // Allow valid CSS custom property references, e.g. var(--wp--preset--spacing--32). + if ( preg_match( '/^var\(--[a-zA-Z0-9_-]+\)$/', $gap_value ) ) { + return $gap_value; + } + return $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value; } diff --git a/phpunit/block-supports/layout-test.php b/phpunit/block-supports/layout-test.php index 368a6290cc376e..66d5860150b5ab 100644 --- a/phpunit/block-supports/layout-test.php +++ b/phpunit/block-supports/layout-test.php @@ -88,22 +88,37 @@ public function test_sanitize_block_gap_value_normalizes_zero_and_rejects_other_ */ public function data_sanitize_block_gap_value() { return array( - 'string value' => array( '1rem', '1rem' ), - 'empty string' => array( '', null ), - 'whitespace-only string' => array( " \t\n", null ), - 'integer zero' => array( 0, '0' ), - 'floating-point zero' => array( 0.0, '0' ), - 'non-zero integer' => array( 1, null ), - 'boolean value' => array( true, null ), - 'object value' => array( new stdClass(), null ), - 'nested array value' => array( + 'string value' => array( '1rem', '1rem' ), + 'empty string' => array( '', null ), + 'whitespace-only string' => array( " \t\n", null ), + 'integer zero' => array( 0, '0' ), + 'floating-point zero' => array( 0.0, '0' ), + 'non-zero integer' => array( 1, null ), + 'boolean value' => array( true, null ), + 'object value' => array( new stdClass(), null ), + 'nested array value' => array( array( 'top' => array( '1rem' ), 'left' => '2rem', ), array( 'left' => '2rem' ), ), - 'empty sanitized array' => array( array( array( '1rem' ) ), null ), + 'empty sanitized array' => array( array( array( '1rem' ) ), null ), + 'valid CSS variable preset' => array( 'var(--wp--preset--spacing--32)', 'var(--wp--preset--spacing--32)' ), + 'valid CSS variable with hyphens' => array( 'var(--wp--preset--spacing--sm-32)', 'var(--wp--preset--spacing--sm-32)' ), + 'valid CSS custom property' => array( 'var(--custom-gap)', 'var(--custom-gap)' ), + 'malformed CSS variable injection' => array( 'var(--wp--preset--spacing--32); background: red;', null ), + 'malformed CSS variable with function' => array( 'var(--wp--preset--spacing--32, url(evil))', null ), + 'nested array with CSS variable' => array( + array( + 'top' => 'var(--wp--preset--spacing--32)', + 'left' => '2rem', + ), + array( + 'top' => 'var(--wp--preset--spacing--32)', + 'left' => '2rem', + ), + ), ); } @@ -555,6 +570,19 @@ public function data_gutenberg_get_layout_style() { ), 'expected_output' => '.wp-layout{grid-template-columns:repeat(auto-fill, minmax(max(min(12rem, 100%), (100% - (1.2rem * (3 - 1))) /3), 1fr));container-type:inline-size;gap:2rem 1.2rem;}', ), + 'grid layout uses preset CSS variable fallback when horizontal gap is missing' => array( + 'args' => array( + 'selector' => '.wp-layout', + 'layout' => array( + 'type' => 'grid', + 'columnCount' => 2, + 'minimumColumnWidth' => '20rem', + ), + 'has_block_gap_support' => true, + 'fallback_gap_value' => 'var(--wp--preset--spacing--32)', + ), + 'expected_output' => '.wp-layout{grid-template-columns:repeat(auto-fill, minmax(max(min(20rem, 100%), (100% - (var(--wp--preset--spacing--32) * (2 - 1))) /2), 1fr));container-type:inline-size;}', + ), 'grid layout preserves zero horizontal gap' => array( 'args' => array( 'selector' => '.wp-layout',