diff --git a/php-transformer/src/HtmlToBlocks/HtmlTransformer.php b/php-transformer/src/HtmlToBlocks/HtmlTransformer.php
index 3b9ff5a..751e6f5 100644
--- a/php-transformer/src/HtmlToBlocks/HtmlTransformer.php
+++ b/php-transformer/src/HtmlToBlocks/HtmlTransformer.php
@@ -1244,16 +1244,13 @@ private function convertElement(DOMElement $element, array &$fallbacks, bool $ca
}
if ( 'canvas' === $tagName ) {
- if ( $this->isDecorativeCanvas($element) && ! $this->isRuntimeCanvasTarget($element) ) {
+ if ( ! $this->isRuntimeCanvasTarget($element) ) {
return null;
}
$this->captureCanvasFallback($element, $fallbacks);
- if ( $this->isRuntimeCanvasTarget($element) ) {
- $boundedHtml = $this->boundedFallbackHtml($this->safeFallbackHtml($element));
- return $this->createBlock('core/html', array( 'content' => $boundedHtml['html'] ), array(), $element);
- }
- return null;
+ $boundedHtml = $this->boundedFallbackHtml($this->safeFallbackHtml($element));
+ return $this->createBlock('core/html', array( 'content' => $boundedHtml['html'] ), array(), $element);
}
if ( 'script' === $tagName ) {
@@ -3094,16 +3091,18 @@ private function captureInlineSvgFallback(DOMElement $element, array &$fallbacks
*/
private function captureCanvasFallback(DOMElement $element, array &$fallbacks): void
{
+ if ( ! $this->isRuntimeCanvasTarget($element) ) {
+ return;
+ }
+
$boundedHtml = $this->boundedFallbackHtml($this->safeFallbackHtml($element));
$id = trim($this->attr($element, 'id'));
- if ( $this->isRuntimeCanvasTarget($element) ) {
- $this->recordRuntimeIsland($element, 'canvas', 'canvas_requires_runtime', 'canvas_element_and_client_script_execution', array(
- 'script_dependency_hint' => '' !== $id
- ? 'Scripts may target #' . $id . ' and call canvas APIs such as getContext(); replacing it with a wrapper block changes runtime behavior.'
- : 'Scripts may target this canvas by selector and call canvas APIs such as getContext(); replacing it with a wrapper block changes runtime behavior.',
- 'required_scripts' => $this->requiredScriptsForElement($element),
- ));
- }
+ $this->recordRuntimeIsland($element, 'canvas', 'canvas_requires_runtime', 'canvas_element_and_client_script_execution', array(
+ 'script_dependency_hint' => '' !== $id
+ ? 'Scripts may target #' . $id . ' and call canvas APIs such as getContext(); replacing it with a wrapper block changes runtime behavior.'
+ : 'Scripts may target this canvas by selector and call canvas APIs such as getContext(); replacing it with a wrapper block changes runtime behavior.',
+ 'required_scripts' => $this->requiredScriptsForElement($element),
+ ));
$fallbacks[] = FallbackDiagnostic::build(array_filter(array(
'type' => 'html',
@@ -3143,16 +3142,6 @@ private function isRuntimeCanvasTarget(DOMElement $element): bool
return false;
}
- private function isDecorativeCanvas(DOMElement $element): bool
- {
- if ( '' !== trim($element->textContent ?? '') || $this->childElementCount($element) > 0 ) {
- return false;
- }
-
- return 'true' === strtolower($this->attr($element, 'aria-hidden'))
- || in_array(strtolower($this->attr($element, 'role')), array('presentation', 'none'), true);
- }
-
/**
* @param array $options
* @return array
diff --git a/php-transformer/tests/contract/run.php b/php-transformer/tests/contract/run.php
index 4b62033..34bfec4 100644
--- a/php-transformer/tests/contract/run.php
+++ b/php-transformer/tests/contract/run.php
@@ -260,12 +260,13 @@ public function match(DOMElement $element, PatternContext $context): ?array
$assertInvalidCanonicalEnvelope($result, 'source_reports.materialization_plan', 'canonical validation can require materialization plans for downstream artifact consumers', true);
$contextual = ( new HtmlTransformer() )->transform(
- 'Context
',
+ 'Context
',
array(
'source' => 'fixture:contextual-html',
'source_scope' => 'contract-test',
'strict' => true,
'allow_fallbacks' => false,
+ 'runtime_canvas_selectors' => array('#runtime-context'),
)
)->toArray();
$assert('failed' === $contextual['status'], 'strict HTML transform fails when fallbacks are disallowed', (string) $contextual['status']);
@@ -573,12 +574,13 @@ public function match(DOMElement $element, PatternContext $context): ?array
}
$assertNormalizedFallbackDiagnostic($diagnosticsByCode['html_unsafe_inline_svg'] ?? array(), 'html_unsafe_inline_svg', 'warning', 'sanitization_review', 'image_asset');
$assertNormalizedFallbackDiagnostic($diagnosticsByCode['html_script_fallback'] ?? array(), 'html_script_fallback', 'warning', 'client_script_execution', 'script_asset');
-$assertNormalizedFallbackDiagnostic($diagnosticsByCode['html_canvas_runtime_fallback'] ?? array(), 'html_canvas_runtime_fallback', 'warning', 'canvas_element_and_client_script_execution', 'runtime_canvas', 'runtime_island_preserved');
$assertNormalizedFallbackDiagnostic($diagnosticsByCode['html_iframe_embed_fallback'] ?? array(), 'html_iframe_embed_fallback', 'warning', 'third_party_embed_runtime', 'embed');
$assert(! isset($diagnosticsByCode['html_inline_svg_fallback']), 'safe inline SVGs convert to image blocks instead of fallback diagnostics');
+$assert(! isset($diagnosticsByCode['html_canvas_runtime_fallback']), 'non-runtime canvas does not emit runtime canvas fallback diagnostics');
$canvasFallback = ( new HtmlTransformer() )->transform(
- ''
+ '',
+ array('runtime_canvas_selectors' => array('#bonsai'))
)->toArray();
$canvasDiagnostic = $canvasFallback['source_reports']['conversion_report']['fallback_diagnostics'][0] ?? array();
$assertNormalizedFallbackDiagnostic($canvasDiagnostic, 'html_canvas_runtime_fallback', 'warning', 'canvas_element_and_client_script_execution', 'runtime_canvas', 'runtime_island_preserved');
@@ -586,8 +588,8 @@ public function match(DOMElement $element, PatternContext $context): ?array
$assert('bonsai' === ($canvasFallback['fallbacks'][0]['attributes']['id'] ?? ''), 'canvas fallback preserves id for runtime mapping');
$assert(str_contains((string) ($canvasFallback['fallbacks'][0]['html'] ?? ''), '