servo: Merge #18510 - Properly handle stacking context collection for truncated fragments (from mrobinson:truncated-fragment-stacking-context-collection); r=emilio
authorMartin Robinson <mrobinson@igalia.com>
Fri, 15 Sep 2017 19:00:24 -0500
changeset 665877 e8d66b5b8f6ba7ea489e8546b5b7603a4cf4f693
parent 665876 62f03c05db7827f2dcc242bb4b58049e09e1398c
child 665878 68a115ea40024978a64f01782e86f6bc53074bdb
push id80212
push usermaglione.k@gmail.com
push dateSat, 16 Sep 2017 04:24:53 +0000
reviewersemilio
milestone57.0a1
servo: Merge #18510 - Properly handle stacking context collection for truncated fragments (from mrobinson:truncated-fragment-stacking-context-collection); r=emilio Before we did not properly descend intro truncated fragments when collecting stacking contexts. This change makes sure that we descend properly Fixes #18254. Fixes #17072. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #18254, #17072 (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 4911706f755f558529cb08f44b0e96be397874ee
servo/components/layout/display_list_builder.rs
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -431,16 +431,20 @@ const INSERTION_POINT_LOGICAL_WIDTH: Au 
 
 pub enum IdType {
     StackingContext,
     OverflowClip,
     CSSClip,
 }
 
 pub trait FragmentDisplayListBuilding {
+    fn collect_stacking_contexts_for_blocklike_fragment(&mut self,
+                                                        state: &mut StackingContextCollectionState)
+                                                        -> bool;
+
     /// Adds the display items necessary to paint the background of this fragment to the display
     /// list if necessary.
     fn build_display_list_for_background_if_applicable(&self,
                                                        state: &mut DisplayListBuildState,
                                                        style: &ComputedValues,
                                                        display_list_section: DisplayListSection,
                                                        absolute_bounds: &Rect<Au>);
 
@@ -902,16 +906,43 @@ fn convert_ellipse_size_keyword(keyword:
         },
         ShapeExtent::FarthestCorner | ShapeExtent::Cover => {
             get_ellipse_radius(size, center, ::std::cmp::max)
         },
     }
 }
 
 impl FragmentDisplayListBuilding for Fragment {
+    fn collect_stacking_contexts_for_blocklike_fragment(&mut self,
+                                                        state: &mut StackingContextCollectionState)
+                                                        -> bool {
+        match self.specific {
+            SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
+                let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref);
+                block_flow.collect_stacking_contexts(state);
+                true
+            }
+            SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
+                let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref);
+                block_flow.collect_stacking_contexts(state);
+                true
+            }
+            SpecificFragmentInfo::InlineAbsolute(ref mut block_flow) => {
+                let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref);
+                block_flow.collect_stacking_contexts(state);
+                true
+            }
+            // FIXME: In the future, if #15144 is fixed we can remove this case. See #18510.
+            SpecificFragmentInfo::TruncatedFragment(ref mut info) => {
+                info.full.collect_stacking_contexts_for_blocklike_fragment(state)
+            }
+            _ => false,
+        }
+    }
+
     fn build_display_list_for_background_if_applicable(&self,
                                                        state: &mut DisplayListBuildState,
                                                        style: &ComputedValues,
                                                        display_list_section: DisplayListSection,
                                                        absolute_bounds: &Rect<Au>) {
         // FIXME: This causes a lot of background colors to be displayed when they are clearly not
         // needed. We could use display list optimization to clean this up, but it still seems
         // inefficient. What we really want is something like "nearest ancestor element that
@@ -2894,44 +2925,34 @@ impl InlineFlowDisplayListBuilding for I
 
         for fragment in self.fragments.fragments.iter_mut() {
             let previous_cb_clip_scroll_info = state.containing_block_clip_and_scroll_info;
             if establishes_containing_block_for_absolute(EstablishContainingBlock::Yes,
                                                          fragment.style.get_box().position) {
                 state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info;
             }
 
-            match fragment.specific {
-                SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
-                    let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref);
-                    block_flow.collect_stacking_contexts(state);
-                }
-                SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
-                    let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref);
-                    block_flow.collect_stacking_contexts(state);
-                }
-                SpecificFragmentInfo::InlineAbsolute(ref mut block_flow) => {
-                    let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref);
-                    block_flow.collect_stacking_contexts(state);
-                }
-                _ if fragment.establishes_stacking_context() => {
+            if !fragment.collect_stacking_contexts_for_blocklike_fragment(state) {
+                if fragment.establishes_stacking_context() {
                     fragment.stacking_context_id = fragment.stacking_context_id();
 
                     let current_stacking_context_id = state.current_stacking_context_id;
-                    let stacking_context = fragment.create_stacking_context(fragment.stacking_context_id,
-                                                                            &self.base,
-                                                                            ScrollPolicy::Scrollable,
-                                                                            StackingContextType::Real,
-                                                                            state.current_clip_and_scroll_info);
-
-                    state.add_stacking_context(current_stacking_context_id,
-                                               stacking_context);
+                    let stacking_context =
+                        fragment.create_stacking_context(fragment.stacking_context_id,
+                                                         &self.base,
+                                                         ScrollPolicy::Scrollable,
+                                                         StackingContextType::Real,
+                                                         state.current_clip_and_scroll_info);
+
+                    state.add_stacking_context(current_stacking_context_id, stacking_context);
+                } else {
+                    fragment.stacking_context_id = state.current_stacking_context_id;
                 }
-                _ => fragment.stacking_context_id = state.current_stacking_context_id,
             }
+
             state.containing_block_clip_and_scroll_info = previous_cb_clip_scroll_info;
         }
 
     }
 
     fn build_display_list_for_inline_fragment_at_index(&mut self,
                                                        state: &mut DisplayListBuildState,
                                                        index: usize) {