From 92c64997bfe8261c439e72ce899cd6fbf3cb1544 Mon Sep 17 00:00:00 2001 From: ldm0 Date: Wed, 2 Sep 2026 17:27:29 +0800 Subject: [PATCH] fix(cssom): refresh child media after iframe resize --- .../context_host/host_environment.rs | 9 ++++++++ .../src/native_bridge/context_host/layout.rs | 21 +++++++++++++++++++ .../stylesheet_and_document_lifecycle.rs | 1 + 3 files changed, 31 insertions(+) diff --git a/moli-renderer-v8/src/native_bridge/context_host/host_environment.rs b/moli-renderer-v8/src/native_bridge/context_host/host_environment.rs index 65faf7318..330b889b0 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/host_environment.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/host_environment.rs @@ -2240,6 +2240,15 @@ impl JsContextHost { if style_mutation_effects_affect_layout_metric(effects) { self.clear_layout_rect_cache(); } + let changed_iframe_attributes = effects.iter().filter_map(|effect| { + let StyleMutationEffect::Attribute { element, name, .. } = effect else { + return None; + }; + (StyleAttributeImpact::for_attribute_name(name).affects_layout_metric() + && self.dom_host().is_html_element_named(*element, "iframe")) + .then_some(*element) + }); + self.invalidate_published_frame_viewports(changed_iframe_attributes); let validity_containers = self.validity_containers_for_child_list_mutations(effects); let dom_host = self.dom_host() as *const _; let emulated_media = self.emulated_media().clone(); diff --git a/moli-renderer-v8/src/native_bridge/context_host/layout.rs b/moli-renderer-v8/src/native_bridge/context_host/layout.rs index fce7d51a8..8e6607a0b 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/layout.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/layout.rs @@ -143,6 +143,27 @@ impl JsContextHost { .frame_viewport(frame) } + pub(crate) fn invalidate_published_frame_viewports( + &self, + frames: impl IntoIterator, + ) { + let frames = frames.into_iter().collect::>(); + if frames.is_empty() { + return; + } + let changed = { + let mut state = self.document_layout_state.borrow_mut(); + let changed = + state.update_frame_viewports(frames.into_iter().map(|frame| (frame, None))); + state.clear_latest_layout(); + changed + }; + if changed { + self.style_viewport_generation + .set(self.style_viewport_generation.get().saturating_add(1)); + } + } + #[cfg(debug_assertions)] pub(crate) fn style_viewport_generation(&self) -> u64 { self.style_viewport_generation.get() diff --git a/moli-renderer-v8/src/script_vm/tests/dom_xhr/computed_style/stylesheet_and_document_lifecycle.rs b/moli-renderer-v8/src/script_vm/tests/dom_xhr/computed_style/stylesheet_and_document_lifecycle.rs index c8490bbfc..0b1071433 100644 --- a/moli-renderer-v8/src/script_vm/tests/dom_xhr/computed_style/stylesheet_and_document_lifecycle.rs +++ b/moli-renderer-v8/src/script_vm/tests/dom_xhr/computed_style/stylesheet_and_document_lifecycle.rs @@ -1093,6 +1093,7 @@ fn computed_style_child_document_media_queries_use_iframe_viewport() { childDocument.open(); childDocument.write('text'); childDocument.close(); + document.body.offsetTop; const before = getComputedStyle(childDocument.body).color; frame.style.width = '200px'; const after = getComputedStyle(childDocument.body).color;