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:
Martin Robinson 2017-09-14 19:46:55 +02:00
parent 89d5780570
commit 73c8947b73
4 changed files with 104 additions and 22 deletions

View file

@ -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;
}

View file

@ -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"

View file

@ -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>

View file

@ -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>