fix(cssom): refresh child media after iframe resize

This commit is contained in:
ldm0
2026-09-27 19:28:50 +08:00
parent 7d0cf9f5ce
commit 92c64997bf
3 changed files with 31 additions and 0 deletions
@@ -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();
@@ -143,6 +143,27 @@ impl JsContextHost {
.frame_viewport(frame)
}
pub(crate) fn invalidate_published_frame_viewports(
&self,
frames: impl IntoIterator<Item = DomHandle>,
) {
let frames = frames.into_iter().collect::<Vec<_>>();
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()
@@ -1093,6 +1093,7 @@ fn computed_style_child_document_media_queries_use_iframe_viewport() {
childDocument.open();
childDocument.write('<style>body { color: red } @media all and (min-width: 101px) { body { color: green } }</style><body>text</body>');
childDocument.close();
document.body.offsetTop;
const before = getComputedStyle(childDocument.body).color;
frame.style.width = '200px';
const after = getComputedStyle(childDocument.body).color;