diff --git a/components/layout/construct.rs b/components/layout/construct.rs index bb7f03721898..b6e21f6d2195 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -1408,88 +1408,98 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> return false } - let mut style = node.style(self.style_context()).clone(); - let mut data = node.mutate_layout_data().unwrap(); - let damage = data.restyle_damage; - match *node.construction_result_mut(&mut *data) { - ConstructionResult::None => true, - ConstructionResult::Flow(ref mut flow, _) => { - // The node's flow is of the same type and has the same set of children and can - // therefore be repaired by simply propagating damage and style to the flow. - if !flow.is_block_flow() { - return false - } - let flow = flow_ref::deref_mut(flow); - flow::mut_base(flow).restyle_damage.insert(damage); - flow.repair_style_and_bubble_inline_sizes(&style); - true - } - ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments( - ref mut inline_fragments_construction_result)) => { - if !inline_fragments_construction_result.splits.is_empty() { - return false - } - - for fragment in inline_fragments_construction_result.fragments - .fragments - .iter_mut() { - // Only mutate the styles of fragments that represent the dirty node (including - // pseudo-element). - if fragment.node != node.opaque() { - continue + let mut set_has_newly_constructed_flow_flag = false; + let result = { + let mut style = node.style(self.style_context()).clone(); + let mut data = node.mutate_layout_data().unwrap(); + let damage = data.restyle_damage; + + match *node.construction_result_mut(&mut *data) { + ConstructionResult::None => true, + ConstructionResult::Flow(ref mut flow, _) => { + // The node's flow is of the same type and has the same set of children and can + // therefore be repaired by simply propagating damage and style to the flow. + if !flow.is_block_flow() { + return false } - if fragment.pseudo != node.get_pseudo_element_type().strip() { - continue + + let flow = flow_ref::deref_mut(flow); + flow::mut_base(flow).restyle_damage.insert(damage); + flow.repair_style_and_bubble_inline_sizes(&style); + true + } + ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments( + ref mut inline_fragments_construction_result)) => { + if !inline_fragments_construction_result.splits.is_empty() { + return false } - match fragment.specific { - SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => { - let flow_ref = flow_ref::deref_mut(&mut inline_block_fragment.flow_ref); - flow::mut_base(flow_ref).restyle_damage.insert(damage); - // FIXME(pcwalton): Fragment restyle damage too? - flow_ref.repair_style_and_bubble_inline_sizes(&style); - } - SpecificFragmentInfo::InlineAbsoluteHypothetical( - ref mut inline_absolute_hypothetical_fragment) => { - let flow_ref = flow_ref::deref_mut( - &mut inline_absolute_hypothetical_fragment.flow_ref); - flow::mut_base(flow_ref).restyle_damage.insert(damage); - // FIXME(pcwalton): Fragment restyle damage too? - flow_ref.repair_style_and_bubble_inline_sizes(&style); + for fragment in inline_fragments_construction_result.fragments + .fragments + .iter_mut() { + // Only mutate the styles of fragments that represent the dirty node (including + // pseudo-element). + if fragment.node != node.opaque() { + continue } - SpecificFragmentInfo::InlineAbsolute(ref mut inline_absolute_fragment) => { - let flow_ref = flow_ref::deref_mut( - &mut inline_absolute_fragment.flow_ref); - flow::mut_base(flow_ref).restyle_damage.insert(damage); - // FIXME(pcwalton): Fragment restyle damage too? - flow_ref.repair_style_and_bubble_inline_sizes(&style); + if fragment.pseudo != node.get_pseudo_element_type().strip() { + continue } - SpecificFragmentInfo::ScannedText(_) => { - // Text fragments in ConstructionResult haven't been scanned yet - unreachable!() - } - SpecificFragmentInfo::GeneratedContent(_) | - SpecificFragmentInfo::UnscannedText(_) => { - // We can't repair this unscanned text; we need to update the - // scanned text fragments. - // - // TODO: Add code to find and repair the ScannedText fragments? - return false - } - _ => { - if node.is_replaced_content() { - properties::modify_style_for_replaced_content(&mut style); + + match fragment.specific { + SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => { + let flow_ref = flow_ref::deref_mut(&mut inline_block_fragment.flow_ref); + flow::mut_base(flow_ref).restyle_damage.insert(damage); + // FIXME(pcwalton): Fragment restyle damage too? + flow_ref.repair_style_and_bubble_inline_sizes(&style); + } + SpecificFragmentInfo::InlineAbsoluteHypothetical( + ref mut inline_absolute_hypothetical_fragment) => { + let flow_ref = flow_ref::deref_mut( + &mut inline_absolute_hypothetical_fragment.flow_ref); + flow::mut_base(flow_ref).restyle_damage.insert(damage); + // FIXME(pcwalton): Fragment restyle damage too? + flow_ref.repair_style_and_bubble_inline_sizes(&style); + } + SpecificFragmentInfo::InlineAbsolute(ref mut inline_absolute_fragment) => { + let flow_ref = flow_ref::deref_mut( + &mut inline_absolute_fragment.flow_ref); + flow::mut_base(flow_ref).restyle_damage.insert(damage); + // FIXME(pcwalton): Fragment restyle damage too? + flow_ref.repair_style_and_bubble_inline_sizes(&style); + } + SpecificFragmentInfo::ScannedText(_) => { + // Text fragments in ConstructionResult haven't been scanned yet + unreachable!() + } + SpecificFragmentInfo::GeneratedContent(_) | + SpecificFragmentInfo::UnscannedText(_) => { + // We can't repair this unscanned text; we need to update the + // scanned text fragments. + // + // TODO: Add code to find and repair the ScannedText fragments? + return false + } + _ => { + if node.is_replaced_content() { + properties::modify_style_for_replaced_content(&mut style); + } + fragment.repair_style(&style); + set_has_newly_constructed_flow_flag = true; } - fragment.repair_style(&style); } } + true + } + ConstructionResult::ConstructionItem(_) => { + false } - true - } - ConstructionResult::ConstructionItem(_) => { - false } + }; + if set_has_newly_constructed_flow_flag { + node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW); } + return result; } }