mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Properly handle stacking context collection for truncated fragments
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.
This commit is contained in:
parent
89d5780570
commit
73c8947b73
4 changed files with 104 additions and 22 deletions
|
@ -436,6 +436,10 @@ pub enum IdType {
|
|||
}
|
||||
|
||||
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,
|
||||
|
@ -907,6 +911,33 @@ fn convert_ellipse_size_keyword(keyword: ShapeExtent,
|
|||
}
|
||||
|
||||
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,
|
||||
|
@ -2899,34 +2930,24 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -6353,6 +6353,18 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/truncated_text_fragment_stacking_context.html": [
|
||||
[
|
||||
"/_mozilla/css/truncated_text_fragment_stacking_context.html",
|
||||
[
|
||||
[
|
||||
"/_mozilla/css/truncated_text_fragment_stacking_context_ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/upper_id_attr.html": [
|
||||
[
|
||||
"/_mozilla/css/upper_id_attr.html",
|
||||
|
@ -10547,6 +10559,11 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/truncated_text_fragment_stacking_context_ref.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/upper_id_attr_ref.html": [
|
||||
[
|
||||
{}
|
||||
|
@ -26893,6 +26910,14 @@
|
|||
"c62420cce19d1d6a7d8700275daaa5ecc10d14c7",
|
||||
"support"
|
||||
],
|
||||
"css/truncated_text_fragment_stacking_context.html": [
|
||||
"453b01aec6ffd3c854fda854cf81250a332cd55c",
|
||||
"reftest"
|
||||
],
|
||||
"css/truncated_text_fragment_stacking_context_ref.html": [
|
||||
"4cb902bb7b058748d1702b5033e8cec729431640",
|
||||
"support"
|
||||
],
|
||||
"css/upper_id_attr.html": [
|
||||
"f9965c1c22379aba20ac08d03a5e0e86cb1d8b99",
|
||||
"reftest"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Truncated text and inline-blocks combined should not cause a panic</title>
|
||||
<link rel="match" href="truncated_text_fragment_stacking_context_ref.html" />
|
||||
<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
|
||||
<meta name="assert" content="This test checks that truncated text and inline-blocks don't cause a panic." />
|
||||
|
||||
<!-- We are using transparent text here to avoid having to deal with subpixel text rendering issues. -->
|
||||
<style>
|
||||
a {
|
||||
float: left;
|
||||
color: transparent;
|
||||
}
|
||||
p, em {
|
||||
overflow:hidden
|
||||
}
|
||||
|
||||
em {
|
||||
display: inline-block;
|
||||
text-overflow: ellipsis;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
div {
|
||||
position: absolute
|
||||
}
|
||||
</style>
|
||||
|
||||
<div style="height: 100px; width: 100px; background: green;"></div>
|
||||
|
||||
<div>
|
||||
<a>LINK</a>
|
||||
<p><em>TEXT</em></p>
|
||||
</div>
|
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Truncated text and inline-blocks combined should not cause a panic</title>
|
||||
<div style="width: 100px; height: 100px; background: green"></div>
|
Loading…
Add table
Add a link
Reference in a new issue