From 4c76f5a84ff9a837058453be7d67e73afe3aed79 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sat, 5 Sep 2026 14:01:59 -0700 Subject: [PATCH] recursively traverse XSL control-flow children under each iframe --- service/media_manager.php | 35 ++++++++++++++++++++-------- tests/service/media_manager_test.php | 24 +++++++++++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/service/media_manager.php b/service/media_manager.php index 83c2f01..fa49ed4 100644 --- a/service/media_manager.php +++ b/service/media_manager.php @@ -197,24 +197,39 @@ protected function rewrite_iframe_node(\DOMElement $iframe) $iframe->removeAttribute('onload'); } - foreach ($iframe->childNodes as $child_node) + $this->rewrite_xsl_iframe_attributes($iframe); + + $iframe->setAttribute('data-consent-media-frame', '1'); + } + + /** + * Rewrite deferred attributes nested inside XSL control-flow elements. + * + * @param \DOMElement $parent Iframe or XSL control-flow element + * + * @return void + */ + protected function rewrite_xsl_iframe_attributes(\DOMElement $parent) + { + foreach ($parent->childNodes as $child_node) { - if (!$child_node instanceof \DOMElement - || $child_node->namespaceURI !== self::XSL_NAMESPACE - || $child_node->localName !== 'attribute' - ) + if (!$child_node instanceof \DOMElement || $child_node->namespaceURI !== self::XSL_NAMESPACE) { continue; } - $name = $child_node->getAttribute('name'); - if ($name === 'src' || $name === 'onload') + if ($child_node->localName === 'attribute') { - $child_node->setAttribute('name', 'data-consent-' . $name); + $name = $child_node->getAttribute('name'); + if ($name === 'src' || $name === 'onload') + { + $child_node->setAttribute('name', 'data-consent-' . $name); + } + continue; } - } - $iframe->setAttribute('data-consent-media-frame', '1'); + $this->rewrite_xsl_iframe_attributes($child_node); + } } /** diff --git a/tests/service/media_manager_test.php b/tests/service/media_manager_test.php index 46f3bf3..a3ca269 100644 --- a/tests/service/media_manager_test.php +++ b/tests/service/media_manager_test.php @@ -299,6 +299,30 @@ public function test_rewrite_iframe_node_rewrites_static_and_xsl_src_and_onload_ self::assertStringNotContainsString(' onload="boot()"', $template); } + public function test_rewrite_iframe_node_rewrites_attributes_nested_in_xsl_control_flow() + { + $dom = \s9e\TextFormatter\Configurator\Helpers\TemplateLoader::load( + '' + ); + $iframe = $dom->getElementsByTagName('iframe')->item(0); + + $this->invoke_method($this->manager, 'rewrite_iframe_node', [$iframe]); + + $template = \s9e\TextFormatter\Configurator\Helpers\TemplateLoader::save($dom); + self::assertSame(2, substr_count($template, 'name="data-consent-src"')); + self::assertStringNotContainsString('name="src"', $template); + self::assertStringContainsString('data-consent-media-frame="1"', $template); + } + protected function invoke_method($object, $method_name, array $arguments = []) { $method = new \ReflectionMethod($object, $method_name);