use bitflags::bitflags;
use style::computed_values::float::T as Float;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::ServoRestyleDamage;
use crate::flow::{Flow, FlowFlags, GetBaseFlow};
#[derive(Clone, Copy, PartialEq)]
pub enum RelayoutMode {
Incremental,
Force,
}
bitflags! {
pub struct SpecialRestyleDamage: u8 {
const REFLOW_ENTIRE_DOCUMENT = 0x01;
}
}
impl dyn Flow {
pub fn compute_layout_damage(&mut self) -> SpecialRestyleDamage {
let mut special_damage = SpecialRestyleDamage::empty();
let is_absolutely_positioned = self
.base()
.flags
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED);
let mut has_counter_affecting_children = false;
{
let self_base = self.mut_base();
let parent_damage = self_base.restyle_damage;
for kid in self_base.children.iter_mut() {
let child_is_absolutely_positioned = kid
.base()
.flags
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED);
kid.mut_base().restyle_damage.insert(
parent_damage
.damage_for_child(is_absolutely_positioned, child_is_absolutely_positioned),
);
{
let kid: &mut dyn Flow = kid;
special_damage.insert(kid.compute_layout_damage());
}
self_base.restyle_damage.insert(
kid.base()
.restyle_damage
.damage_for_parent(child_is_absolutely_positioned),
);
has_counter_affecting_children = has_counter_affecting_children ||
kid.base().flags.intersects(
FlowFlags::AFFECTS_COUNTERS | FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN,
);
}
}
let self_base = self.mut_base();
if self_base.flags.float_kind() != Float::None &&
self_base
.restyle_damage
.intersects(ServoRestyleDamage::REFLOW)
{
special_damage.insert(SpecialRestyleDamage::REFLOW_ENTIRE_DOCUMENT);
}
if has_counter_affecting_children {
self_base
.flags
.insert(FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN)
} else {
self_base
.flags
.remove(FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN)
}
special_damage
}
pub fn reflow_entire_document(&mut self) {
let self_base = self.mut_base();
self_base
.restyle_damage
.insert(RestyleDamage::rebuild_and_reflow());
self_base
.restyle_damage
.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
for kid in self_base.children.iter_mut() {
kid.reflow_entire_document();
}
}
}