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
--- 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) {