tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 6cb49e422cad3e0bba008296df7d5929b25e8b43
parent 04b013b47241e496684d5f7eb4368c0898166d87
Author: Denis Palmeiro <dpalmeiro@mozilla.com>
Date:   Tue, 30 Dec 2025 15:43:10 +0000

Bug 2006172: Allow style sharing across shadow hosts. r=emilio,firefox-style-system-reviewers

Allow shadow hosts to share styles when they have the same CascadeData pointer,
ensuring they have the same :host rules. Improves TodoMVC-WebComponents by ~10%.

Differential Revision: https://phabricator.services.mozilla.com/D277357

Diffstat:
Mservo/components/style/sharing/mod.rs | 27+++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/servo/components/style/sharing/mod.rs b/servo/components/style/sharing/mod.rs @@ -68,7 +68,7 @@ use crate::applicable_declarations::ApplicableDeclarationBlock; use crate::bloom::StyleBloom; use crate::computed_value_flags::ComputedValueFlags; use crate::context::{SharedStyleContext, StyleContext}; -use crate::dom::{SendElement, TElement}; +use crate::dom::{SendElement, TElement, TShadowRoot}; use crate::properties::ComputedValues; use crate::rule_tree::StrongRuleNode; use crate::selector_map::RelevantAttributes; @@ -654,16 +654,6 @@ impl<E: TElement> StyleSharingCache<E> { return; } - // We can't share style across shadow hosts right now, because they may - // match different :host rules. - // - // TODO(emilio): We could share across the ones that don't have :host - // rules or have the same. - if element.shadow_root().is_some() { - debug!("Failing to insert into the cache: Shadow Host"); - return; - } - // If the element has running animations, we can't share style. // // This is distinct from the specifies_{animations,transitions} check below, @@ -817,9 +807,18 @@ impl<E: TElement> StyleSharingCache<E> { return None; } - if target.element.shadow_root().is_some() { - trace!("Miss: Shadow host"); - return None; + // Shadow hosts can share style when they have matching CascadeData pointers, which + // ensures they match the same :host rules. + match ( + target.element.shadow_root().and_then(|s| s.style_data()), + candidate.element.shadow_root().and_then(|s| s.style_data()), + ) { + (Some(td), Some(cd)) if std::ptr::eq(td, cd) => {}, + (None, None) => {}, + _ => { + trace!("Miss: Different shadow root style data"); + return None; + }, } if target.element.has_animations(shared_context)