diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-08-04 12:53:26 -0600 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-08-04 12:53:26 -0600 |
commit | 56d3426431d98a6f43698f33bb7ce4d3ad67adeb (patch) | |
tree | acf8f93b9e6c3341a6b95bc527d8b95d393bde9b | |
parent | 220557008318350b444ba1917a3b07e03d30bec5 (diff) | |
parent | 0a589d413d03b11198033e34b28cb24bed99c0fb (diff) | |
download | servo-56d3426431d98a6f43698f33bb7ce4d3ad67adeb.tar.gz servo-56d3426431d98a6f43698f33bb7ce4d3ad67adeb.zip |
Auto merge of #6940 - pcwalton:inline-pseudo-repair-jumpiness, r=mbrubeck
layout: When repairing styles for incremental reflow, only repair styles of nodes that represent the dirty node, *including its pseudo-element*.
r? @mbrubeck
<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6940)
<!-- Reviewable:end -->
-rw-r--r-- | components/layout/construct.rs | 19 | ||||
-rw-r--r-- | components/layout/fragment.rs | 10 | ||||
-rw-r--r-- | components/layout/generated_content.rs | 11 | ||||
-rw-r--r-- | components/layout/inline.rs | 5 | ||||
-rw-r--r-- | components/layout/wrapper.rs | 22 | ||||
-rw-r--r-- | tests/html/inline-pseudo-repair-jumpiness.html | 1 |
6 files changed, 55 insertions, 13 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 9ab1dfc6675..5060eaa3bbd 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -105,7 +105,7 @@ pub enum ConstructionItem { /// Inline fragments and associated {ib} splits that have not yet found flows. InlineFragments(InlineFragmentsConstructionResult), /// Potentially ignorable whitespace. - Whitespace(OpaqueNode, Arc<ComputedValues>, RestyleDamage), + Whitespace(OpaqueNode, PseudoElementType<()>, Arc<ComputedValues>, RestyleDamage), /// TableColumn Fragment TableColumnFragment(Fragment), } @@ -217,6 +217,7 @@ impl InlineFragmentsAccumulator { fragments: IntermediateInlineFragments::new(), enclosing_node: Some(InlineFragmentNodeInfo { address: node.opaque(), + pseudo: node.get_pseudo_element_type().strip(), style: node.style().clone(), }), bidi_control_chars: None, @@ -573,6 +574,7 @@ impl<'a> FlowConstructor<'a> { } ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( whitespace_node, + whitespace_pseudo, mut whitespace_style, whitespace_damage)) => { // Add whitespace results. They will be stripped out later on when @@ -581,6 +583,7 @@ impl<'a> FlowConstructor<'a> { UnscannedTextFragmentInfo::from_text(" ".to_owned())); properties::modify_style_for_replaced_content(&mut whitespace_style); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, + whitespace_pseudo, whitespace_style, whitespace_damage, fragment_info); @@ -712,6 +715,8 @@ impl<'a> FlowConstructor<'a> { fragments.fragments .push_back(Fragment::from_opaque_node_and_style(node.opaque(), + node.get_pseudo_element_type() + .strip(), style.clone(), node.restyle_damage(), specific)) @@ -793,12 +798,14 @@ impl<'a> FlowConstructor<'a> { } else { // Push the absolutely-positioned kid as an inline containing block. let kid_node = flow.as_block().fragment.node; + let kid_pseudo = flow.as_block().fragment.pseudo.clone(); let kid_style = flow.as_block().fragment.style.clone(); let kid_restyle_damage = flow.as_block().fragment.restyle_damage; let fragment_info = SpecificFragmentInfo::InlineAbsolute( InlineAbsoluteFragmentInfo::new(flow)); fragment_accumulator.push(Fragment::from_opaque_node_and_style( kid_node, + kid_pseudo, kid_style, kid_restyle_damage, fragment_info)); @@ -826,6 +833,7 @@ impl<'a> FlowConstructor<'a> { } ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( whitespace_node, + whitespace_pseudo, mut whitespace_style, whitespace_damage)) => { // Instantiate the whitespace fragment. @@ -833,6 +841,7 @@ impl<'a> FlowConstructor<'a> { UnscannedTextFragmentInfo::from_text(" ".to_owned())); properties::modify_style_for_replaced_content(&mut whitespace_style); let fragment = Fragment::from_opaque_node_and_style(whitespace_node, + whitespace_pseudo, whitespace_style, whitespace_damage, fragment_info); @@ -875,6 +884,7 @@ impl<'a> FlowConstructor<'a> { if node.is_ignorable_whitespace() { return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace( node.opaque(), + node.get_pseudo_element_type().strip(), node.style().clone(), node.restyle_damage())) } @@ -1295,10 +1305,14 @@ impl<'a> FlowConstructor<'a> { for fragment in inline_fragments_construction_result.fragments .fragments .iter_mut() { - // Only mutate the styles of fragments that represent the dirty node. + // Only mutate the styles of fragments that represent the dirty node (including + // pseudo-element). if fragment.node != node.opaque() { continue } + if fragment.pseudo != node.get_pseudo_element_type().strip() { + continue + } match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut inline_block_fragment) => { @@ -1689,6 +1703,7 @@ fn control_chars_to_fragment(node: &InlineFragmentNodeInfo, text: &str, let info = SpecificFragmentInfo::UnscannedText( UnscannedTextFragmentInfo::from_text(String::from(text))); Fragment::from_opaque_node_and_style(node.address, + node.pseudo, node.style.clone(), restyle_damage, info) diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 61a6042b6df..1f7ecce5fe9 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -17,7 +17,7 @@ use inline::{InlineFragmentContext, InlineFragmentNodeInfo, InlineMetrics}; use layout_debug; use model::{self, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified}; use text; -use wrapper::ThreadSafeLayoutNode; +use wrapper::{PseudoElementType, ThreadSafeLayoutNode}; use euclid::{Point2D, Rect, Size2D}; use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode}; @@ -107,6 +107,9 @@ pub struct Fragment { /// How damaged this fragment is since last reflow. pub restyle_damage: RestyleDamage, + /// The pseudo-element that this fragment represents. + pub pseudo: PseudoElementType<()>, + /// A debug ID that is consistent for the life of this fragment (via transform etc). pub debug_id: u16, } @@ -752,6 +755,7 @@ impl Fragment { margin: LogicalMargin::zero(writing_mode), specific: specific, inline_context: None, + pseudo: node.get_pseudo_element_type().strip(), debug_id: layout_debug::generate_unique_debug_id(), } } @@ -782,12 +786,14 @@ impl Fragment { margin: LogicalMargin::zero(writing_mode), specific: specific, inline_context: None, + pseudo: node.get_pseudo_element_type().strip(), debug_id: layout_debug::generate_unique_debug_id(), } } /// Constructs a new `Fragment` instance from an opaque node. pub fn from_opaque_node_and_style(node: OpaqueNode, + pseudo: PseudoElementType<()>, style: Arc<ComputedValues>, restyle_damage: RestyleDamage, specific: SpecificFragmentInfo) @@ -802,6 +808,7 @@ impl Fragment { margin: LogicalMargin::zero(writing_mode), specific: specific, inline_context: None, + pseudo: pseudo, debug_id: layout_debug::generate_unique_debug_id(), } } @@ -834,6 +841,7 @@ impl Fragment { margin: self.margin, specific: info, inline_context: self.inline_context.clone(), + pseudo: self.pseudo.clone(), debug_id: self.debug_id, } } diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs index a5803d2484c..6e9f5da9918 100644 --- a/components/layout/generated_content.rs +++ b/components/layout/generated_content.rs @@ -15,6 +15,7 @@ use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTe use incremental::{self, RESOLVE_GENERATED_CONTENT}; use smallvec::SmallVec; use text::TextRunScanner; +use wrapper::PseudoElementType; use gfx::display_list::OpaqueNode; use std::collections::{LinkedList, HashMap}; @@ -174,6 +175,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> { GeneratedContentInfo::ListItem => { new_info = self.traversal.list_item.render(self.traversal.layout_context, fragment.node, + fragment.pseudo.clone(), fragment.style.clone(), list_style_type, RenderingMode::Suffix(".\u{00a0}")) @@ -190,6 +192,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> { .unwrap_or(&mut temporary_counter); new_info = counter.render(self.traversal.layout_context, fragment.node, + fragment.pseudo.clone(), fragment.style.clone(), counter_style, RenderingMode::Plain) @@ -204,6 +207,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> { .unwrap_or(&mut temporary_counter); new_info = counter.render(self.traversal.layout_context, fragment.node, + fragment.pseudo, fragment.style.clone(), counter_style, RenderingMode::All(&separator)); @@ -211,6 +215,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> { GeneratedContentInfo::ContentItem(ContentItem::OpenQuote) => { new_info = Some(render_text(self.traversal.layout_context, fragment.node, + fragment.pseudo, fragment.style.clone(), self.quote(&*fragment.style, false))); self.traversal.quote += 1 @@ -222,6 +227,7 @@ impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> { new_info = Some(render_text(self.traversal.layout_context, fragment.node, + fragment.pseudo, fragment.style.clone(), self.quote(&*fragment.style, true))); } @@ -356,6 +362,7 @@ impl Counter { fn render(&self, layout_context: &LayoutContext, node: OpaqueNode, + pseudo: PseudoElementType<()>, style: Arc<ComputedValues>, list_style_type: list_style_type::T, mode: RenderingMode) @@ -392,7 +399,7 @@ impl Counter { if string.is_empty() { None } else { - Some(render_text(layout_context, node, style, string)) + Some(render_text(layout_context, node, pseudo, style, string)) } } } @@ -418,12 +425,14 @@ struct CounterValue { /// Creates fragment info for a literal string. fn render_text(layout_context: &LayoutContext, node: OpaqueNode, + pseudo: PseudoElementType<()>, style: Arc<ComputedValues>, string: String) -> SpecificFragmentInfo { let mut fragments = LinkedList::new(); let info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(string)); fragments.push_back(Fragment::from_opaque_node_and_style(node, + pseudo, style, incremental::rebuild_and_reflow(), info)); diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 6d4d67e6bbb..78363d0451c 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -15,6 +15,7 @@ use incremental::{REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT}; use layout_debug; use model::IntrinsicISizesContribution; use text; +use wrapper::PseudoElementType; use euclid::{Point2D, Rect, Size2D}; use gfx::display_list::OpaqueNode; @@ -1349,8 +1350,7 @@ impl Flow for InlineFlow { self.base.block_container_explicit_block_size; for fragment in self.fragments.fragments.iter_mut() { fragment.update_late_computed_replaced_inline_size_if_necessary(); - fragment.assign_replaced_block_size_if_necessary( - containing_block_block_size); + fragment.assign_replaced_block_size_if_necessary(containing_block_block_size); } // Reset our state, so that we handle incremental reflow correctly. @@ -1687,6 +1687,7 @@ impl fmt::Debug for InlineFlow { pub struct InlineFragmentNodeInfo { pub address: OpaqueNode, pub style: Arc<ComputedValues>, + pub pseudo: PseudoElementType<()>, } #[derive(Clone)] diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 26378daf40c..93e52192d64 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -588,13 +588,13 @@ impl<'le> TElementAttributes for LayoutElement<'le> { } #[derive(Copy, PartialEq, Clone)] -pub enum PseudoElementType { +pub enum PseudoElementType<T> { Normal, - Before(display::T), - After(display::T), + Before(T), + After(T), } -impl PseudoElementType { +impl<T> PseudoElementType<T> { pub fn is_before(&self) -> bool { match *self { PseudoElementType::Before(_) => true, @@ -608,6 +608,14 @@ impl PseudoElementType { _ => false, } } + + pub fn strip(&self) -> PseudoElementType<()> { + match *self { + PseudoElementType::Normal => PseudoElementType::Normal, + PseudoElementType::Before(_) => PseudoElementType::Before(()), + PseudoElementType::After(_) => PseudoElementType::After(()), + } + } } /// A thread-safe version of `LayoutNode`, used during flow construction. This type of layout @@ -617,7 +625,7 @@ pub struct ThreadSafeLayoutNode<'ln> { /// The wrapped node. node: LayoutNode<'ln>, - pseudo: PseudoElementType, + pseudo: PseudoElementType<display::T>, } impl<'ln> ThreadSafeLayoutNode<'ln> { @@ -639,7 +647,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { /// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode` /// with a different pseudo-element type. - fn with_pseudo(&self, pseudo: PseudoElementType) -> ThreadSafeLayoutNode<'ln> { + fn with_pseudo(&self, pseudo: PseudoElementType<display::T>) -> ThreadSafeLayoutNode<'ln> { ThreadSafeLayoutNode { node: self.node.clone(), pseudo: pseudo, @@ -697,7 +705,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> { } #[inline] - pub fn get_pseudo_element_type(&self) -> PseudoElementType { + pub fn get_pseudo_element_type(&self) -> PseudoElementType<display::T> { self.pseudo } diff --git a/tests/html/inline-pseudo-repair-jumpiness.html b/tests/html/inline-pseudo-repair-jumpiness.html new file mode 100644 index 00000000000..d95c12f939c --- /dev/null +++ b/tests/html/inline-pseudo-repair-jumpiness.html @@ -0,0 +1 @@ +<body>a<br>b</body> |