From b607b3a9322dc69e4d5629f27f78830483c31a66 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Fri, 15 Apr 2016 15:36:32 -0700 Subject: [PATCH] Fix meld_with_next_inline_fragment and add meld_with_prev_inline_fragment Factor out a new `meld_with_prev_inline_fragment` method that mirrors the existing `meld_with_next_inline_fragment`. This also fixes a bug in `meld_with_next` that was already fixed in the `meld_with_prev` by @notriddle in #10419. The bug is that it was traversing the inline context nodes in the wrong order. It should start at the outermost enclosing node, since the fragments might be at different nesting levels under some common ancestor. --- components/layout/construct.rs | 23 +------------------- components/layout/fragment.rs | 39 +++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 4099e1f9af5..8bf1a416484 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -1779,28 +1779,7 @@ pub fn strip_ignorable_whitespace_from_start(this: &mut LinkedList) { WhitespaceStrippingResult::FragmentContainedOnlyWhitespace => { let removed_fragment = this.pop_front().unwrap(); if let Some(ref mut remaining_fragment) = this.front_mut() { - if let Some(ref mut inline_context_of_remaining_fragment) = - remaining_fragment.inline_context { - if let Some(ref inline_context_of_removed_fragment) = - removed_fragment.inline_context { - for (inline_context_node_from_removed_fragment, - inline_context_node_from_remaining_fragment) in - inline_context_of_removed_fragment.nodes.iter().rev().zip( - inline_context_of_remaining_fragment.nodes.iter_mut().rev() - ) { - if !inline_context_node_from_removed_fragment.flags.contains( - FIRST_FRAGMENT_OF_ELEMENT) { - continue - } - if inline_context_node_from_removed_fragment.address != - inline_context_node_from_remaining_fragment.address { - continue - } - inline_context_node_from_remaining_fragment.flags.insert( - FIRST_FRAGMENT_OF_ELEMENT); - } - } - } + remaining_fragment.meld_with_prev_inline_fragment(&removed_fragment); } } } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 6aacfe8b175..8f2d5b83af1 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -2497,26 +2497,49 @@ impl Fragment { pub fn meld_with_next_inline_fragment(&mut self, next_fragment: &Fragment) { if let Some(ref mut inline_context_of_this_fragment) = self.inline_context { if let Some(ref inline_context_of_next_fragment) = next_fragment.inline_context { - for (i, inline_context_node_from_next_fragment) in - inline_context_of_next_fragment.nodes.iter().enumerate() { - if i >= inline_context_of_this_fragment.nodes.len() { - continue - } + for (inline_context_node_from_this_fragment, + inline_context_node_from_next_fragment) + in inline_context_of_this_fragment.nodes.iter_mut().rev() + .zip(inline_context_of_next_fragment.nodes.iter().rev()) + { if !inline_context_node_from_next_fragment.flags.contains( LAST_FRAGMENT_OF_ELEMENT) { continue } if inline_context_node_from_next_fragment.address != - inline_context_of_this_fragment.nodes[i].address { + inline_context_node_from_this_fragment.address { continue } - inline_context_of_this_fragment.nodes[i].flags.insert( - LAST_FRAGMENT_OF_ELEMENT); + inline_context_node_from_this_fragment.flags.insert(LAST_FRAGMENT_OF_ELEMENT); } } } } + pub fn meld_with_prev_inline_fragment(&mut self, prev_fragment: &Fragment) { + if let Some(ref mut inline_context_of_this_fragment) = self.inline_context { + if let Some(ref inline_context_of_prev_fragment) = prev_fragment.inline_context { + for (inline_context_node_from_prev_fragment, + inline_context_node_from_this_fragment) + in inline_context_of_prev_fragment.nodes.iter().rev().zip( + inline_context_of_this_fragment.nodes.iter_mut().rev()) + { + if !inline_context_node_from_prev_fragment.flags.contains( + FIRST_FRAGMENT_OF_ELEMENT) { + continue + } + if inline_context_node_from_prev_fragment.address != + inline_context_node_from_this_fragment.address { + continue + } + inline_context_node_from_this_fragment.flags.insert( + FIRST_FRAGMENT_OF_ELEMENT); + } + } + } + } + + pub fn fragment_id(&self) -> usize { return self as *const Fragment as usize; }