script: Ensure notify_invalidations() is always called when modifying stylesheets (#38530)

This change supplements the missing stylesheet invalidation
notifications to fix some bugs that the modification of stylesheet does
not take effect. Additionally, this PR add a RAII thing to mark the
modification scope of stylesheet rules, which will facilitate to add
extra logic before the modification happens.

Fixes: there is relevant issue #38211 , but it can't be fixed by this
PR.
Testing: This fixes some subtests in
`/css/cssom/CSSStyleSheet-constructable.html`.

Signed-off-by: sharpshooter_pt <ibluegalaxy_taoj@163.com>
This commit is contained in:
JoeDow 2025-08-15 17:14:34 +08:00 committed by GitHub
parent aca4bde93d
commit 8b574539d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 8 additions and 11 deletions

View file

@ -114,6 +114,7 @@ impl CSSKeyframesRuleMethods<crate::DomTypeHolder> for CSSKeyframesRule {
.keyframes .keyframes
.push(rule); .push(rule);
self.rulelist(can_gc).append_lazy_dom_rule(); self.rulelist(can_gc).append_lazy_dom_rule();
self.cssrule.parent_stylesheet().notify_invalidations();
} }
} }
@ -145,6 +146,7 @@ impl CSSKeyframesRuleMethods<crate::DomTypeHolder> for CSSKeyframesRule {
let name = KeyframesName::from_ident(&value); let name = KeyframesName::from_ident(&value);
let mut guard = self.cssrule.shared_lock().write(); let mut guard = self.cssrule.shared_lock().write();
self.keyframesrule.write_with(&mut guard).name = name; self.keyframesrule.write_with(&mut guard).name = name;
self.cssrule.parent_stylesheet().notify_invalidations();
Ok(()) Ok(())
} }
} }

View file

@ -148,6 +148,7 @@ impl CSSRuleList {
self.dom_rules self.dom_rules
.borrow_mut() .borrow_mut()
.insert(index, MutNullableDom::new(Some(&*dom_rule))); .insert(index, MutNullableDom::new(Some(&*dom_rule)));
parent_stylesheet.notify_invalidations();
Ok(idx) Ok(idx)
} }
@ -167,6 +168,7 @@ impl CSSRuleList {
r.detach() r.detach()
} }
dom_rules.remove(index); dom_rules.remove(index);
self.parent_stylesheet.notify_invalidations();
Ok(()) Ok(())
}, },
RulesSource::Keyframes(ref kf) => { RulesSource::Keyframes(ref kf) => {
@ -177,6 +179,7 @@ impl CSSRuleList {
} }
dom_rules.remove(index); dom_rules.remove(index);
kf.write_with(&mut guard).keyframes.remove(index); kf.write_with(&mut guard).keyframes.remove(index);
self.parent_stylesheet.notify_invalidations();
Ok(()) Ok(())
}, },
} }

View file

@ -125,8 +125,6 @@ impl CSSStyleOwner {
f(&mut *pdb.write_with(&mut guard), &mut changed) f(&mut *pdb.write_with(&mut guard), &mut changed)
}; };
if changed { if changed {
// If this is changed, see also
// CSSStyleRule::SetSelectorText, which does the same thing.
rule.parent_stylesheet().notify_invalidations(); rule.parent_stylesheet().notify_invalidations();
} }
result result

View file

@ -126,6 +126,7 @@ impl MediaListMethods<crate::DomTypeHolder> for MediaList {
let mut guard = self.shared_lock().write(); let mut guard = self.shared_lock().write();
let media_queries = self.media_queries.write_with(&mut guard); let media_queries = self.media_queries.write_with(&mut guard);
*media_queries = Self::parse_media_list(&value, global.as_window()); *media_queries = Self::parse_media_list(&value, global.as_window());
self.parent_stylesheet.notify_invalidations();
} }
// https://drafts.csswg.org/cssom/#dom-medialist-length // https://drafts.csswg.org/cssom/#dom-medialist-length
@ -171,6 +172,7 @@ impl MediaListMethods<crate::DomTypeHolder> for MediaList {
} }
// Step 4 // Step 4
mq.media_queries.push(m.unwrap()); mq.media_queries.push(m.unwrap());
self.parent_stylesheet.notify_invalidations();
} }
/// <https://drafts.csswg.org/cssom/#dom-medialist-deletemedium> /// <https://drafts.csswg.org/cssom/#dom-medialist-deletemedium>
@ -192,5 +194,6 @@ impl MediaListMethods<crate::DomTypeHolder> for MediaList {
.filter(|q| m_serialized != q.to_css_string()) .filter(|q| m_serialized != q.to_css_string())
.collect(); .collect();
media_list.media_queries = new_vec; media_list.media_queries = new_vec;
self.parent_stylesheet.notify_invalidations();
} }
} }

View file

@ -11,18 +11,9 @@
[Re-attaching shadow host with adopted stylesheets work] [Re-attaching shadow host with adopted stylesheets work]
expected: FAIL expected: FAIL
[Changes to constructed stylesheets through CSSOM is reflected]
expected: FAIL
[Constructed stylesheet can be used and modified in multiple TreeScopes] [Constructed stylesheet can be used and modified in multiple TreeScopes]
expected: FAIL expected: FAIL
[Stylesheets constructed on the main Document cannot be used in iframes]
expected: FAIL
[Stylesheet constructed on iframe cannot be used in the main Document]
expected: FAIL
[CSSStyleSheet.replaceSync correctly updates the style of its adopters synchronously] [CSSStyleSheet.replaceSync correctly updates the style of its adopters synchronously]
expected: FAIL expected: FAIL