mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
style: Make the allocation of AuthorStyles for ShadowRoot lazy.
So that we don't waste a bunch of memory with stuff like <svg:use>. I plan to shrink AuthorStyles further, but this should help regardless, and isn't very complex. Differential Revision: https://phabricator.services.mozilla.com/D4618
This commit is contained in:
parent
1bc452703b
commit
1e6aa62c6f
3 changed files with 41 additions and 28 deletions
|
@ -342,7 +342,7 @@ pub trait TShadowRoot: Sized + Copy + Clone + PartialEq {
|
|||
fn host(&self) -> <Self::ConcreteNode as TNode>::ConcreteElement;
|
||||
|
||||
/// Get the style data for this ShadowRoot.
|
||||
fn style_data<'a>(&self) -> &'a CascadeData
|
||||
fn style_data<'a>(&self) -> Option<&'a CascadeData>
|
||||
where
|
||||
Self: 'a;
|
||||
|
||||
|
@ -824,30 +824,36 @@ pub trait TElement:
|
|||
|
||||
if let Some(shadow) = self.containing_shadow() {
|
||||
doc_rules_apply = false;
|
||||
f(
|
||||
shadow.style_data(),
|
||||
self.as_node().owner_doc().quirks_mode(),
|
||||
Some(shadow.host()),
|
||||
);
|
||||
if let Some(data) = shadow.style_data() {
|
||||
f(
|
||||
data,
|
||||
self.as_node().owner_doc().quirks_mode(),
|
||||
Some(shadow.host()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(shadow) = self.shadow_root() {
|
||||
f(
|
||||
shadow.style_data(),
|
||||
self.as_node().owner_doc().quirks_mode(),
|
||||
Some(shadow.host()),
|
||||
);
|
||||
if let Some(data) = shadow.style_data() {
|
||||
f(
|
||||
data,
|
||||
self.as_node().owner_doc().quirks_mode(),
|
||||
Some(shadow.host()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let mut current = self.assigned_slot();
|
||||
while let Some(slot) = current {
|
||||
// Slots can only have assigned nodes when in a shadow tree.
|
||||
let shadow = slot.containing_shadow().unwrap();
|
||||
f(
|
||||
shadow.style_data(),
|
||||
self.as_node().owner_doc().quirks_mode(),
|
||||
Some(shadow.host()),
|
||||
);
|
||||
if let Some(data) = shadow.style_data() {
|
||||
f(
|
||||
data,
|
||||
self.as_node().owner_doc().quirks_mode(),
|
||||
Some(shadow.host()),
|
||||
);
|
||||
}
|
||||
current = slot.assigned_slot();
|
||||
}
|
||||
|
||||
|
|
|
@ -167,15 +167,14 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn style_data<'a>(&self) -> &'a CascadeData
|
||||
fn style_data<'a>(&self) -> Option<&'a CascadeData>
|
||||
where
|
||||
Self: 'a,
|
||||
{
|
||||
debug_assert!(!self.0.mServoStyles.mPtr.is_null());
|
||||
|
||||
let author_styles = unsafe {
|
||||
&*(self.0.mServoStyles.mPtr as *const structs::RawServoAuthorStyles
|
||||
as *const bindings::RawServoAuthorStyles)
|
||||
(self.0.mServoStyles.mPtr
|
||||
as *const structs::RawServoAuthorStyles
|
||||
as *const bindings::RawServoAuthorStyles).as_ref()?
|
||||
};
|
||||
|
||||
|
||||
|
@ -187,7 +186,7 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> {
|
|||
author_styles.stylesheets.dirty()
|
||||
);
|
||||
|
||||
&author_styles.data
|
||||
Some(&author_styles.data)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -1206,7 +1206,7 @@ impl Stylist {
|
|||
// to add some sort of AuthorScoped cascade level or something.
|
||||
if matches_author_rules {
|
||||
if let Some(shadow) = rule_hash_target.shadow_root() {
|
||||
if let Some(map) = shadow.style_data().host_rules(pseudo_element) {
|
||||
if let Some(map) = shadow.style_data().and_then(|data| data.host_rules(pseudo_element)) {
|
||||
context.with_shadow_host(Some(rule_hash_target), |context| {
|
||||
map.get_all_matching_rules(
|
||||
element,
|
||||
|
@ -1233,8 +1233,7 @@ impl Stylist {
|
|||
|
||||
for slot in slots.iter().rev() {
|
||||
let shadow = slot.containing_shadow().unwrap();
|
||||
let styles = shadow.style_data();
|
||||
if let Some(map) = styles.slotted_rules(pseudo_element) {
|
||||
if let Some(map) = shadow.style_data().and_then(|data| data.slotted_rules(pseudo_element)) {
|
||||
context.with_shadow_host(Some(shadow.host()), |context| {
|
||||
map.get_all_matching_rules(
|
||||
element,
|
||||
|
@ -1253,7 +1252,7 @@ impl Stylist {
|
|||
if let Some(containing_shadow) = rule_hash_target.containing_shadow() {
|
||||
let cascade_data = containing_shadow.style_data();
|
||||
let host = containing_shadow.host();
|
||||
if let Some(map) = cascade_data.normal_rules(pseudo_element) {
|
||||
if let Some(map) = cascade_data.and_then(|data| data.normal_rules(pseudo_element)) {
|
||||
context.with_shadow_host(Some(host), |context| {
|
||||
map.get_all_matching_rules(
|
||||
element,
|
||||
|
@ -1283,6 +1282,11 @@ impl Stylist {
|
|||
//
|
||||
// See: https://github.com/w3c/svgwg/issues/505
|
||||
//
|
||||
// FIXME(emilio, bug 1487259): We now do after bug 1483882, we
|
||||
// should jump out of the <svg:use> shadow tree chain now.
|
||||
//
|
||||
// Unless the used node is cross-doc, I guess, in which case doc
|
||||
// rules are probably ok...
|
||||
let host_is_svg_use =
|
||||
host.is_svg_element() &&
|
||||
host.local_name() == &*local_name!("use");
|
||||
|
@ -1431,11 +1435,15 @@ impl Stylist {
|
|||
// [2]: https://github.com/w3c/csswg-drafts/issues/1995
|
||||
// [3]: https://bugzil.la/1458189
|
||||
if let Some(shadow) = element.shadow_root() {
|
||||
try_find_in!(shadow.style_data());
|
||||
if let Some(data) = shadow.style_data() {
|
||||
try_find_in!(data);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(shadow) = element.containing_shadow() {
|
||||
try_find_in!(shadow.style_data());
|
||||
if let Some(data) = shadow.style_data() {
|
||||
try_find_in!(data);
|
||||
}
|
||||
} else {
|
||||
try_find_in!(self.cascade_data.author);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue