Update flags for absolutely positioned elements on style changes

Fixes #17307.
This commit is contained in:
Matt Brubeck 2017-06-30 14:32:06 -07:00
parent f01e1da01e
commit 2aef2af9b8
7 changed files with 96 additions and 5 deletions

View file

@ -12,7 +12,7 @@ path = "lib.rs"
[dependencies]
app_units = "0.5"
atomic_refcell = "0.1"
bitflags = "0.7"
bitflags = "0.8"
canvas_traits = {path = "../canvas_traits"}
euclid = "0.15"
fnv = "1.0"

View file

@ -1115,6 +1115,28 @@ impl BaseFlow {
}
}
/// Update the 'flags' field when computed styles have changed.
///
/// These flags are initially set during flow construction. They only need to be updated here
/// if they are based on properties that can change without triggering `RECONSTRUCT_FLOW`.
pub fn update_flags_if_needed(&mut self, style: &ServoComputedValues) {
// For absolutely-positioned flows, changes to top/bottom/left/right can cause these flags
// to get out of date:
if self.restyle_damage.contains(REFLOW_OUT_OF_FLOW) {
// Note: We don't need to check whether IS_ABSOLUTELY_POSITIONED has changed, because
// changes to the 'position' property trigger flow reconstruction.
if self.flags.contains(IS_ABSOLUTELY_POSITIONED) {
let logical_position = style.logical_position();
self.flags.set(INLINE_POSITION_IS_STATIC,
logical_position.inline_start == LengthOrPercentageOrAuto::Auto &&
logical_position.inline_end == LengthOrPercentageOrAuto::Auto);
self.flags.set(BLOCK_POSITION_IS_STATIC,
logical_position.block_start == LengthOrPercentageOrAuto::Auto &&
logical_position.block_end == LengthOrPercentageOrAuto::Auto);
}
}
}
/// Return a new BaseFlow like this one but with the given children list
pub fn clone_with_children(&self, children: FlowList) -> BaseFlow {
BaseFlow {
@ -1361,6 +1383,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
/// calling them individually, since there is no reason not to perform both operations.
fn repair_style_and_bubble_inline_sizes(self, style: &::StyleArc<ServoComputedValues>) {
self.repair_style(style);
mut_base(self).update_flags_if_needed(style);
self.bubble_inline_sizes();
}