mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Allow the ComputedValues in ComputedStyle to be null.
This is necessary to start synthesizing the styles in match_element and avoid round-tripping them through the caller.
This commit is contained in:
parent
1c530f9279
commit
5873de3fb6
8 changed files with 53 additions and 32 deletions
|
@ -777,7 +777,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
|
||||||
debug_assert!(self.is_text_node());
|
debug_assert!(self.is_text_node());
|
||||||
let parent = self.node.parent_node().unwrap().as_element().unwrap();
|
let parent = self.node.parent_node().unwrap().as_element().unwrap();
|
||||||
let parent_data = parent.get_data().unwrap().borrow();
|
let parent_data = parent.get_data().unwrap().borrow();
|
||||||
parent_data.styles().primary.values.clone()
|
parent_data.styles().primary.values().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn debug_id(self) -> usize {
|
fn debug_id(self) -> usize {
|
||||||
|
|
|
@ -389,7 +389,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
fn style(&self, context: &SharedStyleContext) -> Arc<ServoComputedValues> {
|
fn style(&self, context: &SharedStyleContext) -> Arc<ServoComputedValues> {
|
||||||
match self.get_pseudo_element_type() {
|
match self.get_pseudo_element_type() {
|
||||||
PseudoElementType::Normal => self.get_style_data().unwrap().borrow()
|
PseudoElementType::Normal => self.get_style_data().unwrap().borrow()
|
||||||
.styles().primary.values.clone(),
|
.styles().primary.values().clone(),
|
||||||
other => {
|
other => {
|
||||||
// Precompute non-eagerly-cascaded pseudo-element styles if not
|
// Precompute non-eagerly-cascaded pseudo-element styles if not
|
||||||
// cached before.
|
// cached before.
|
||||||
|
@ -406,7 +406,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
let new_style =
|
let new_style =
|
||||||
context.stylist.precomputed_values_for_pseudo(
|
context.stylist.precomputed_values_for_pseudo(
|
||||||
&style_pseudo,
|
&style_pseudo,
|
||||||
Some(&data.styles().primary.values),
|
Some(data.styles().primary.values()),
|
||||||
&context.default_computed_values,
|
&context.default_computed_values,
|
||||||
false);
|
false);
|
||||||
data.styles_mut().pseudos
|
data.styles_mut().pseudos
|
||||||
|
@ -424,7 +424,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
.lazily_compute_pseudo_element_style(
|
.lazily_compute_pseudo_element_style(
|
||||||
unsafe { &self.unsafe_get() },
|
unsafe { &self.unsafe_get() },
|
||||||
&style_pseudo,
|
&style_pseudo,
|
||||||
&data.styles().primary.values,
|
data.styles().primary.values(),
|
||||||
&context.default_computed_values);
|
&context.default_computed_values);
|
||||||
data.styles_mut().pseudos
|
data.styles_mut().pseudos
|
||||||
.insert(style_pseudo.clone(), new_style.unwrap());
|
.insert(style_pseudo.clone(), new_style.unwrap());
|
||||||
|
@ -434,7 +434,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
|
|
||||||
self.get_style_data().unwrap().borrow()
|
self.get_style_data().unwrap().borrow()
|
||||||
.styles().pseudos.get(&style_pseudo)
|
.styles().pseudos.get(&style_pseudo)
|
||||||
.unwrap().values.clone()
|
.unwrap().values().clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,7 +445,7 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
data.styles().pseudos
|
data.styles().pseudos
|
||||||
.get(&PseudoElement::Selection).map(|s| s)
|
.get(&PseudoElement::Selection).map(|s| s)
|
||||||
.unwrap_or(&data.styles().primary)
|
.unwrap_or(&data.styles().primary)
|
||||||
.values.clone()
|
.values().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the already resolved style of the node.
|
/// Returns the already resolved style of the node.
|
||||||
|
@ -460,10 +460,10 @@ pub trait ThreadSafeLayoutElement: Clone + Copy + Sized + Debug +
|
||||||
let data = self.get_style_data().unwrap().borrow();
|
let data = self.get_style_data().unwrap().borrow();
|
||||||
match self.get_pseudo_element_type() {
|
match self.get_pseudo_element_type() {
|
||||||
PseudoElementType::Normal
|
PseudoElementType::Normal
|
||||||
=> data.styles().primary.values.clone(),
|
=> data.styles().primary.values().clone(),
|
||||||
other
|
other
|
||||||
=> data.styles().pseudos
|
=> data.styles().pseudos
|
||||||
.get(&other.style_pseudo_element()).unwrap().values.clone(),
|
.get(&other.style_pseudo_element()).unwrap().values().clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,9 @@ pub struct ComputedStyle {
|
||||||
pub rules: StrongRuleNode,
|
pub rules: StrongRuleNode,
|
||||||
|
|
||||||
/// The computed values for each property obtained by cascading the
|
/// The computed values for each property obtained by cascading the
|
||||||
/// matched rules.
|
/// matched rules. This can only be none during a transient interval of
|
||||||
pub values: Arc<ComputedValues>,
|
/// the styling algorithm, and callers can safely unwrap it.
|
||||||
|
pub values: Option<Arc<ComputedValues>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComputedStyle {
|
impl ComputedStyle {
|
||||||
|
@ -39,9 +40,29 @@ impl ComputedStyle {
|
||||||
pub fn new(rules: StrongRuleNode, values: Arc<ComputedValues>) -> Self {
|
pub fn new(rules: StrongRuleNode, values: Arc<ComputedValues>) -> Self {
|
||||||
ComputedStyle {
|
ComputedStyle {
|
||||||
rules: rules,
|
rules: rules,
|
||||||
values: values,
|
values: Some(values),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a partial ComputedStyle, whose ComputedVaues will be filled
|
||||||
|
/// in later.
|
||||||
|
pub fn new_partial(rules: StrongRuleNode) -> Self {
|
||||||
|
ComputedStyle {
|
||||||
|
rules: rules,
|
||||||
|
values: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the ComputedValues. The values can only be null during
|
||||||
|
/// the styling algorithm, so this is safe to call elsewhere.
|
||||||
|
pub fn values(&self) -> &Arc<ComputedValues> {
|
||||||
|
self.values.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mutable version of the above.
|
||||||
|
pub fn values_mut(&mut self) -> &mut Arc<ComputedValues> {
|
||||||
|
self.values.as_mut().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We manually implement Debug for ComputedStyle so that we can avoid the
|
// We manually implement Debug for ComputedStyle so that we can avoid the
|
||||||
|
@ -121,7 +142,7 @@ impl ElementStyles {
|
||||||
|
|
||||||
/// Whether this element `display` value is `none`.
|
/// Whether this element `display` value is `none`.
|
||||||
pub fn is_display_none(&self) -> bool {
|
pub fn is_display_none(&self) -> bool {
|
||||||
self.primary.values.get_box().clone_display() == display::T::none
|
self.primary.values().get_box().clone_display() == display::T::none
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,7 @@ fn fmt_with_data_and_primary_values<N: TNode>(f: &mut fmt::Formatter, n: N) -> f
|
||||||
let dd = el.has_dirty_descendants();
|
let dd = el.has_dirty_descendants();
|
||||||
let data = el.borrow_data();
|
let data = el.borrow_data();
|
||||||
let styles = data.as_ref().and_then(|d| d.get_styles());
|
let styles = data.as_ref().and_then(|d| d.get_styles());
|
||||||
let values = styles.map(|s| &s.primary.values);
|
let values = styles.map(|s| s.primary.values());
|
||||||
write!(f, "{:?} dd={} data={:?} values={:?}", el, dd, &data, values)
|
write!(f, "{:?} dd={} data={:?} values={:?}", el, dd, &data, values)
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{:?}", n)
|
write!(f, "{:?}", n)
|
||||||
|
|
|
@ -737,9 +737,9 @@ pub trait MatchMethods : TElement {
|
||||||
// can decide more easily if it knows that it's a child of
|
// can decide more easily if it knows that it's a child of
|
||||||
// replaced content, or similar stuff!
|
// replaced content, or similar stuff!
|
||||||
let maybe_damage = {
|
let maybe_damage = {
|
||||||
let previous = data.get_styles().map(|x| &x.primary.values);
|
let previous = data.get_styles().map(|x| x.primary.values());
|
||||||
let existing = self.existing_style_for_restyle_damage(previous, None);
|
let existing = self.existing_style_for_restyle_damage(previous, None);
|
||||||
existing.map(|e| RestyleDamage::compute(e, &shared_style.values))
|
existing.map(|e| RestyleDamage::compute(e, &shared_style.values()))
|
||||||
};
|
};
|
||||||
if let Some(d) = maybe_damage {
|
if let Some(d) = maybe_damage {
|
||||||
data.restyle_mut().damage |= d;
|
data.restyle_mut().damage |= d;
|
||||||
|
@ -887,7 +887,7 @@ pub trait MatchMethods : TElement {
|
||||||
// specific with that frame, but not wanting to flush all of
|
// specific with that frame, but not wanting to flush all of
|
||||||
// layout).
|
// layout).
|
||||||
debug_assert!(cfg!(feature = "gecko") || d.has_current_styles());
|
debug_assert!(cfg!(feature = "gecko") || d.has_current_styles());
|
||||||
&d.styles().primary.values
|
d.styles().primary.values()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut new_styles;
|
let mut new_styles;
|
||||||
|
@ -901,9 +901,9 @@ pub trait MatchMethods : TElement {
|
||||||
// Update animations before the cascade. This may modify the
|
// Update animations before the cascade. This may modify the
|
||||||
// value of the old primary style.
|
// value of the old primary style.
|
||||||
self.update_animations_for_cascade(&context.shared,
|
self.update_animations_for_cascade(&context.shared,
|
||||||
&mut previous.primary.values,
|
previous.primary.values_mut(),
|
||||||
&mut possibly_expired_animations);
|
&mut possibly_expired_animations);
|
||||||
(Some(&previous.primary.values), Some(&mut previous.pseudos))
|
(Some(previous.primary.values()), Some(&mut previous.pseudos))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -924,7 +924,7 @@ pub trait MatchMethods : TElement {
|
||||||
let damage =
|
let damage =
|
||||||
self.compute_damage_and_cascade_pseudos(old_primary,
|
self.compute_damage_and_cascade_pseudos(old_primary,
|
||||||
old_pseudos,
|
old_pseudos,
|
||||||
&new_styles.primary.values,
|
&new_styles.primary.values(),
|
||||||
&mut new_styles.pseudos,
|
&mut new_styles.pseudos,
|
||||||
context,
|
context,
|
||||||
pseudo_rule_nodes,
|
pseudo_rule_nodes,
|
||||||
|
@ -987,7 +987,7 @@ pub trait MatchMethods : TElement {
|
||||||
// Update animations before the cascade. This may modify
|
// Update animations before the cascade. This may modify
|
||||||
// the value of old_pseudo_style.
|
// the value of old_pseudo_style.
|
||||||
self.update_animations_for_cascade(&context.shared,
|
self.update_animations_for_cascade(&context.shared,
|
||||||
&mut old_pseudo_style.values,
|
old_pseudo_style.values_mut(),
|
||||||
possibly_expired_animations);
|
possibly_expired_animations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,7 +996,7 @@ pub trait MatchMethods : TElement {
|
||||||
self.cascade_node_pseudo_element(context,
|
self.cascade_node_pseudo_element(context,
|
||||||
Some(new_primary),
|
Some(new_primary),
|
||||||
maybe_old_pseudo_style.as_ref()
|
maybe_old_pseudo_style.as_ref()
|
||||||
.map(|s| &s.values),
|
.map(|s| s.values()),
|
||||||
&new_rule_node,
|
&new_rule_node,
|
||||||
&possibly_expired_animations,
|
&possibly_expired_animations,
|
||||||
CascadeBooleans {
|
CascadeBooleans {
|
||||||
|
@ -1008,7 +1008,7 @@ pub trait MatchMethods : TElement {
|
||||||
if damage != rebuild_and_reflow {
|
if damage != rebuild_and_reflow {
|
||||||
damage = damage | match maybe_old_pseudo_style {
|
damage = damage | match maybe_old_pseudo_style {
|
||||||
None => rebuild_and_reflow,
|
None => rebuild_and_reflow,
|
||||||
Some(ref old) => self.compute_restyle_damage(Some(&old.values),
|
Some(ref old) => self.compute_restyle_damage(Some(old.values()),
|
||||||
&new_pseudo_values,
|
&new_pseudo_values,
|
||||||
Some(&pseudo)),
|
Some(&pseudo)),
|
||||||
};
|
};
|
||||||
|
|
|
@ -349,7 +349,7 @@ impl Stylist {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.precomputed_values_for_pseudo(&pseudo, Some(parent_style), default_style, inherit_all)
|
self.precomputed_values_for_pseudo(&pseudo, Some(parent_style), default_style, inherit_all)
|
||||||
.values
|
.values.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a pseudo-element style lazily during layout.
|
/// Computes a pseudo-element style lazily during layout.
|
||||||
|
|
|
@ -246,7 +246,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
||||||
// recursively drops Servo ElementData when the XBL insertion parent of
|
// recursively drops Servo ElementData when the XBL insertion parent of
|
||||||
// an Element is changed.
|
// an Element is changed.
|
||||||
if cfg!(feature = "gecko") && thread_local.is_initial_style() &&
|
if cfg!(feature = "gecko") && thread_local.is_initial_style() &&
|
||||||
parent_data.styles().primary.values.has_moz_binding() {
|
parent_data.styles().primary.values().has_moz_binding() {
|
||||||
if log.allow() { debug!("Parent {:?} has XBL binding, deferring traversal", parent); }
|
if log.allow() { debug!("Parent {:?} has XBL binding, deferring traversal", parent); }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -552,7 +552,7 @@ fn compute_style<E, D>(_traversal: &D,
|
||||||
context.thread_local
|
context.thread_local
|
||||||
.style_sharing_candidate_cache
|
.style_sharing_candidate_cache
|
||||||
.insert_if_possible(&element,
|
.insert_if_possible(&element,
|
||||||
&data.styles().primary.values,
|
data.styles().primary.values(),
|
||||||
match_results.relations);
|
match_results.relations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -683,7 +683,7 @@ pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
|
||||||
let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
|
let maybe_parent = ComputedValues::arc_from_borrowed(&parent_style_or_null);
|
||||||
data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent,
|
data.stylist.precomputed_values_for_pseudo(&pseudo, maybe_parent,
|
||||||
data.default_computed_values(), false)
|
data.default_computed_values(), false)
|
||||||
.values
|
.values.unwrap()
|
||||||
.into_strong()
|
.into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,7 +709,7 @@ pub extern "C" fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
|
||||||
|
|
||||||
match get_pseudo_style(element, pseudo_tag, data.styles(), doc_data) {
|
match get_pseudo_style(element, pseudo_tag, data.styles(), doc_data) {
|
||||||
Some(values) => values.into_strong(),
|
Some(values) => values.into_strong(),
|
||||||
None if !is_probe => data.styles().primary.values.clone().into_strong(),
|
None if !is_probe => data.styles().primary.values().clone().into_strong(),
|
||||||
None => Strong::null(),
|
None => Strong::null(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,13 +720,13 @@ fn get_pseudo_style(element: GeckoElement, pseudo_tag: *mut nsIAtom,
|
||||||
{
|
{
|
||||||
let pseudo = PseudoElement::from_atom_unchecked(Atom::from(pseudo_tag), false);
|
let pseudo = PseudoElement::from_atom_unchecked(Atom::from(pseudo_tag), false);
|
||||||
match SelectorImpl::pseudo_element_cascade_type(&pseudo) {
|
match SelectorImpl::pseudo_element_cascade_type(&pseudo) {
|
||||||
PseudoElementCascadeType::Eager => styles.pseudos.get(&pseudo).map(|s| s.values.clone()),
|
PseudoElementCascadeType::Eager => styles.pseudos.get(&pseudo).map(|s| s.values().clone()),
|
||||||
PseudoElementCascadeType::Precomputed => unreachable!("No anonymous boxes"),
|
PseudoElementCascadeType::Precomputed => unreachable!("No anonymous boxes"),
|
||||||
PseudoElementCascadeType::Lazy => {
|
PseudoElementCascadeType::Lazy => {
|
||||||
let d = doc_data.borrow_mut();
|
let d = doc_data.borrow_mut();
|
||||||
let base = &styles.primary.values;
|
let base = styles.primary.values();
|
||||||
d.stylist.lazily_compute_pseudo_element_style(&element, &pseudo, base, &d.default_computed_values())
|
d.stylist.lazily_compute_pseudo_element_style(&element, &pseudo, base, &d.default_computed_values())
|
||||||
.map(|s| s.values.clone())
|
.map(|s| s.values().clone())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1167,7 +1167,7 @@ pub extern "C" fn Servo_ResolveStyle(element: RawGeckoElementBorrowed,
|
||||||
return per_doc_data.default_computed_values().clone().into_strong();
|
return per_doc_data.default_computed_values().clone().into_strong();
|
||||||
}
|
}
|
||||||
|
|
||||||
data.styles().primary.values.clone().into_strong()
|
data.styles().primary.values().clone().into_strong()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -1184,7 +1184,7 @@ pub extern "C" fn Servo_ResolveStyleLazily(element: RawGeckoElementBorrowed,
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
maybe_pseudo.unwrap_or_else(|| styles.primary.values.clone())
|
maybe_pseudo.unwrap_or_else(|| styles.primary.values().clone())
|
||||||
};
|
};
|
||||||
|
|
||||||
// In the common case we already have the style. Check that before setting
|
// In the common case we already have the style. Check that before setting
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue