From abfb58421e0867ead650171f0b78669ce8f8fa6e Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Thu, 3 Sep 2026 09:25:50 -0400 Subject: [PATCH] Preserve hidden accessibility support text --- .../Style/SourceBlockAttributeProjector.php | 14 ++++++++++++++ .../unit/inert-closed-state-interactions.php | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/php-transformer/src/HtmlToBlocks/Style/SourceBlockAttributeProjector.php b/php-transformer/src/HtmlToBlocks/Style/SourceBlockAttributeProjector.php index 31d45415..278bd861 100644 --- a/php-transformer/src/HtmlToBlocks/Style/SourceBlockAttributeProjector.php +++ b/php-transformer/src/HtmlToBlocks/Style/SourceBlockAttributeProjector.php @@ -58,6 +58,9 @@ public function project( if ( 'core/group' === $name && $facts->isAuthorLayoutItem ) { $attrs['className'] = SourceDom::mergeClassNames((string) ($attrs['className'] ?? ''), self::CSS_OWNED_LAYOUT_ITEM_CLASS); } + if ( in_array($name, array( 'core/group', 'core/paragraph' ), true) && self::isHiddenAccessibilitySupportElement($sourceElement) ) { + $attrs['className'] = SourceDom::mergeClassNames((string) ($attrs['className'] ?? ''), self::HIDDEN_RICH_TEXT_MARKER_CLASS); + } if ( 'core/group' === $name && $this->isAtomicInlineChildFlow($sourceElement, $innerBlocks) ) { $attrs['className'] = SourceDom::mergeClassNames((string) ($attrs['className'] ?? ''), self::CSS_OWNED_INLINE_FLOW_CLASS); } @@ -90,6 +93,17 @@ public function project( return $attrs; } + private static function isHiddenAccessibilitySupportElement(DOMElement $element): bool + { + $identity = strtolower(SourceDom::attr($element, 'id') . ' ' . SourceDom::attr($element, 'class')); + if ( 1 !== preg_match('/(?:a11y|accessib|screen[-_]?reader|sr[-_]?only|visually[-_]?hidden)/', $identity) ) { + return false; + } + + $style = strtolower(SourceDom::attr($element, 'style')); + return 1 === preg_match('/(?:^|;)\s*(?:display\s*:\s*none|visibility\s*:\s*hidden)\s*(?:!important)?\s*(?:;|$)/', $style); + } + public function sourceProjectionClassName(DOMElement $element, SourceBlockAttributeProjectionContext $context, string $className = ''): string { $sourceTagMarker = $context->selectorProjections->tagMarker(strtolower($element->tagName)); diff --git a/php-transformer/tests/unit/inert-closed-state-interactions.php b/php-transformer/tests/unit/inert-closed-state-interactions.php index db7c8a94..decd312b 100644 --- a/php-transformer/tests/unit/inert-closed-state-interactions.php +++ b/php-transformer/tests/unit/inert-closed-state-interactions.php @@ -335,6 +335,23 @@ $boundaryMarkerAfterAuthor ); +$hiddenNavigationSupport = <<<'HTML' + + + +HTML; + +$hiddenNavigationSupportResult = ( new HtmlTransformer() )->transform($hiddenNavigationSupport)->toArray(); +$hiddenNavigationSupportMarkup = (string) ($hiddenNavigationSupportResult['serialized_blocks'] ?? ''); +$hiddenNavigationSupportBeforeAuthor = $cssContent($hiddenNavigationSupportResult, 'before-author', 'both'); +$assert( + str_contains($hiddenNavigationSupportMarkup, 'Use tab to navigate through the menu items.') + && str_contains($hiddenNavigationSupportMarkup, 'blocks-engine-hidden-richtext-marker') + && str_contains($hiddenNavigationSupportBeforeAuthor, ':where(.blocks-engine-hidden-richtext-marker){display:none}'), + 'an explicitly hidden navigation accessibility support group retains its hidden state', + $hiddenNavigationSupportMarkup . "\n" . $hiddenNavigationSupportBeforeAuthor +); + if ( $failures > 0 ) { fwrite(STDERR, "inert closed-state interactions: {$failures} failed, {$passes} passed\n"); exit(1);