Repository: servo/servo
File: components/layout/traversal.rs (Rust)

Code before:

    // Only propagate up layout phases from children, as other types of damage are
    // incorporated into `element_damage` above.
    let mut damage_for_parent = element_damage | (damage_from_children & RestyleDamage::RELAYOUT);

    // If we are going to potentially reuse this box tree node, then clear any cached
    // fragment layout.
    //
    // TODO: If this node has `recollect_box_tree_children` damage, this is unnecessary
    // unless it's entirely above the dirty root.
    if element_damage != RestyleDamage::reconstruct() &&
        damage_for_parent.contains(RestyleDamage::RELAYOUT)
    {
        let outer_inline_content_sizes_depend_on_content = Cell::new(false);
        node.with_each_layout_box_base_including_pseudos(|base| {
            base.clear_fragments();
            if original_element_damage.contains(RestyleDamage::RELAYOUT) {
                *base.cached_layout_result.borrow_mut() = None;
                *base.cached_inline_content_size.borrow_mut() = None;
            } else if damage_from_children.contains(RestyleDamage::RELAYOUT) {
                *base.cached_layout_result.borrow_mut() = None;
                if !damage_from_children.contains(LayoutDamage::recompute_inline_content_sizes()) {
                    return;
                }
                *base.cached_inline_content_size.borrow_mut() = None;
            }
            if !base.base_fragment_info.is_anonymous() {
                // TODO: Use `Cell::update()` once it becomes stable.
                outer_inline_content_sizes_depend_on_content.set(
                    outer_inline_content_sizes_depend_on_content.get() ||
                        base.outer_inline_content_sizes_depend_on_content
                            .load(Ordering::Relaxed),
                );
            }
        });
        if outer_inline_content_sizes_depend_on_content.get() {
            damage_for_parent.insert(LayoutDamage::recompute_inline_content_sizes())
        }
    }

    // If the box will be preserved, update the box's style and also in any fragments
    // that haven't been cleared. Meanwhile, clear the damage to avoid affecting the
    // next reflow.
    if !element_layout_damage.has_box_damage() {
        if !original_element_damage.is_empty() {
            node.repair_style(context);
        }

        element_damage = RestyleDamage::empty();
    }


Review comment (suggestion):
```suggestion
                // This can happen when a descendent doesn't have layout damage and doesn't depend
                // on content size -- for instance when it is has a fixed inline size.
                if !damage_from_children.contains(LayoutDamage::recompute_inline_content_sizes()) {
```

Code after:

    // Only propagate up layout phases from children, as other types of damage are
    // incorporated into `element_damage` above.
    let mut damage_for_parent = element_damage | (damage_from_children & RestyleDamage::RELAYOUT);

    // If we are going to potentially reuse this box tree node, then clear any cached
    // fragment layout.
    //
    // TODO: If this node has `recollect_box_tree_children` damage, this is unnecessary
    // unless it's entirely above the dirty root.
    if element_damage != RestyleDamage::reconstruct() &&
        damage_for_parent.contains(RestyleDamage::RELAYOUT)
    {
        let outer_inline_content_sizes_depend_on_content = Cell::new(false);
        node.with_each_layout_box_base_including_pseudos(|base| {
            base.clear_fragments();
            if original_element_damage.contains(RestyleDamage::RELAYOUT) {
                // If the node itself has damage, we must clear both the cached layout results
                // and also the cached intrinsic inline sizes.
                *base.cached_layout_result.borrow_mut() = None;
                *base.cached_inline_content_size.borrow_mut() = None;
            } else if damage_from_children.contains(RestyleDamage::RELAYOUT) {
                // If the damage is propagated from children, then we still need to clear the cached
                // layout results, but sometimes we can keep the cached intrinsic inline sizes.
                *base.cached_layout_result.borrow_mut() = None;
                if !damage_from_children.contains(LayoutDamage::recompute_inline_content_sizes()) {
                    // This happens when there is a node which is a descendant of the current one and
                    // an ancestor of the damaged one, whose inline size doesn't depend on its contents.
                    return;
                }
                *base.cached_inline_content_size.borrow_mut() = None;
            }

            // When a block container has a mix of inline-level and block-level contents,
            // the inline-level ones are wrapped inside an anonymous block associated with
            // the block container. The anonymous block has an `auto` size, so its intrinsic
            // contribution depends on content, but it can't affect the intrinsic size of
            // ancestors if the block container is sized extrinsically.
            if !base.base_fragment_info.is_anonymous() {
                // TODO: Use `Cell::update()` once it becomes stable.
                outer_inline_content_sizes_depend_on_content.set(
                    outer_inline_content_sizes_depend_on_content.get() ||
                        base.outer_inline_content_sizes_depend_on_content
                            .load(Ordering::Relaxed),
                );
            }
        });

        // If the intrinsic contributions of this node depend on content, we will need to clear
        // the cached intrinsic sizes of the parent. But if the contributions are purely extrinsic,
        // then the intrinsic sizes of the ancestors won't be affected, and we can keep the cache.