mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +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;
|
fn host(&self) -> <Self::ConcreteNode as TNode>::ConcreteElement;
|
||||||
|
|
||||||
/// Get the style data for this ShadowRoot.
|
/// Get the style data for this ShadowRoot.
|
||||||
fn style_data<'a>(&self) -> &'a CascadeData
|
fn style_data<'a>(&self) -> Option<&'a CascadeData>
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
|
|
||||||
|
@ -824,30 +824,36 @@ pub trait TElement:
|
||||||
|
|
||||||
if let Some(shadow) = self.containing_shadow() {
|
if let Some(shadow) = self.containing_shadow() {
|
||||||
doc_rules_apply = false;
|
doc_rules_apply = false;
|
||||||
f(
|
if let Some(data) = shadow.style_data() {
|
||||||
shadow.style_data(),
|
f(
|
||||||
self.as_node().owner_doc().quirks_mode(),
|
data,
|
||||||
Some(shadow.host()),
|
self.as_node().owner_doc().quirks_mode(),
|
||||||
);
|
Some(shadow.host()),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(shadow) = self.shadow_root() {
|
if let Some(shadow) = self.shadow_root() {
|
||||||
f(
|
if let Some(data) = shadow.style_data() {
|
||||||
shadow.style_data(),
|
f(
|
||||||
self.as_node().owner_doc().quirks_mode(),
|
data,
|
||||||
Some(shadow.host()),
|
self.as_node().owner_doc().quirks_mode(),
|
||||||
);
|
Some(shadow.host()),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut current = self.assigned_slot();
|
let mut current = self.assigned_slot();
|
||||||
while let Some(slot) = current {
|
while let Some(slot) = current {
|
||||||
// Slots can only have assigned nodes when in a shadow tree.
|
// Slots can only have assigned nodes when in a shadow tree.
|
||||||
let shadow = slot.containing_shadow().unwrap();
|
let shadow = slot.containing_shadow().unwrap();
|
||||||
f(
|
if let Some(data) = shadow.style_data() {
|
||||||
shadow.style_data(),
|
f(
|
||||||
self.as_node().owner_doc().quirks_mode(),
|
data,
|
||||||
Some(shadow.host()),
|
self.as_node().owner_doc().quirks_mode(),
|
||||||
);
|
Some(shadow.host()),
|
||||||
|
);
|
||||||
|
}
|
||||||
current = slot.assigned_slot();
|
current = slot.assigned_slot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,15 +167,14 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn style_data<'a>(&self) -> &'a CascadeData
|
fn style_data<'a>(&self) -> Option<&'a CascadeData>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
debug_assert!(!self.0.mServoStyles.mPtr.is_null());
|
|
||||||
|
|
||||||
let author_styles = unsafe {
|
let author_styles = unsafe {
|
||||||
&*(self.0.mServoStyles.mPtr as *const structs::RawServoAuthorStyles
|
(self.0.mServoStyles.mPtr
|
||||||
as *const bindings::RawServoAuthorStyles)
|
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.stylesheets.dirty()
|
||||||
);
|
);
|
||||||
|
|
||||||
&author_styles.data
|
Some(&author_styles.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -1206,7 +1206,7 @@ impl Stylist {
|
||||||
// to add some sort of AuthorScoped cascade level or something.
|
// to add some sort of AuthorScoped cascade level or something.
|
||||||
if matches_author_rules {
|
if matches_author_rules {
|
||||||
if let Some(shadow) = rule_hash_target.shadow_root() {
|
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| {
|
context.with_shadow_host(Some(rule_hash_target), |context| {
|
||||||
map.get_all_matching_rules(
|
map.get_all_matching_rules(
|
||||||
element,
|
element,
|
||||||
|
@ -1233,8 +1233,7 @@ impl Stylist {
|
||||||
|
|
||||||
for slot in slots.iter().rev() {
|
for slot in slots.iter().rev() {
|
||||||
let shadow = slot.containing_shadow().unwrap();
|
let shadow = slot.containing_shadow().unwrap();
|
||||||
let styles = shadow.style_data();
|
if let Some(map) = shadow.style_data().and_then(|data| data.slotted_rules(pseudo_element)) {
|
||||||
if let Some(map) = styles.slotted_rules(pseudo_element) {
|
|
||||||
context.with_shadow_host(Some(shadow.host()), |context| {
|
context.with_shadow_host(Some(shadow.host()), |context| {
|
||||||
map.get_all_matching_rules(
|
map.get_all_matching_rules(
|
||||||
element,
|
element,
|
||||||
|
@ -1253,7 +1252,7 @@ impl Stylist {
|
||||||
if let Some(containing_shadow) = rule_hash_target.containing_shadow() {
|
if let Some(containing_shadow) = rule_hash_target.containing_shadow() {
|
||||||
let cascade_data = containing_shadow.style_data();
|
let cascade_data = containing_shadow.style_data();
|
||||||
let host = containing_shadow.host();
|
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| {
|
context.with_shadow_host(Some(host), |context| {
|
||||||
map.get_all_matching_rules(
|
map.get_all_matching_rules(
|
||||||
element,
|
element,
|
||||||
|
@ -1283,6 +1282,11 @@ impl Stylist {
|
||||||
//
|
//
|
||||||
// See: https://github.com/w3c/svgwg/issues/505
|
// 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 =
|
let host_is_svg_use =
|
||||||
host.is_svg_element() &&
|
host.is_svg_element() &&
|
||||||
host.local_name() == &*local_name!("use");
|
host.local_name() == &*local_name!("use");
|
||||||
|
@ -1431,11 +1435,15 @@ impl Stylist {
|
||||||
// [2]: https://github.com/w3c/csswg-drafts/issues/1995
|
// [2]: https://github.com/w3c/csswg-drafts/issues/1995
|
||||||
// [3]: https://bugzil.la/1458189
|
// [3]: https://bugzil.la/1458189
|
||||||
if let Some(shadow) = element.shadow_root() {
|
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() {
|
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 {
|
} else {
|
||||||
try_find_in!(self.cascade_data.author);
|
try_find_in!(self.cascade_data.author);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue