Fix panic when tables having position:sticky

We no longer do any stacking context or clip node creation for table
wrappers, instead relying on their TableFlows to do this.
This commit is contained in:
Martin Robinson 2017-09-14 12:19:50 +02:00
parent 89d5780570
commit f1596e83a9
11 changed files with 78 additions and 33 deletions

View file

@ -103,11 +103,10 @@ fn convert_repeat_mode(from: RepeatKeyword) -> RepeatMode {
}
}
fn establishes_containing_block_for_absolute(can_establish_containing_block: EstablishContainingBlock,
fn establishes_containing_block_for_absolute(flags: StackingContextCollectionFlags,
positioning: position::T)
-> bool {
can_establish_containing_block == EstablishContainingBlock::Yes &&
position::T::static_ != positioning
!flags.contains(NEVER_CREATES_CONTAINING_BLOCK) && position::T::static_ != positioning
}
trait RgbColor {
@ -2312,16 +2311,19 @@ impl FragmentDisplayListBuilding for Fragment {
}
}
#[derive(Clone, Copy, PartialEq)]
pub enum EstablishContainingBlock {
Yes,
No,
bitflags! {
pub flags StackingContextCollectionFlags: u8 {
/// This flow never establishes a containing block.
const NEVER_CREATES_CONTAINING_BLOCK = 0x01,
/// This flow never creates a ClipScrollNode.
const NEVER_CREATES_CLIP_SCROLL_NODE = 0x02,
}
}
pub trait BlockFlowDisplayListBuilding {
fn collect_stacking_contexts_for_block(&mut self,
state: &mut StackingContextCollectionState,
can_establish_containing_block: EstablishContainingBlock);
flags: StackingContextCollectionFlags);
fn transform_clip_to_coordinate_space(&mut self,
state: &mut StackingContextCollectionState,
@ -2330,7 +2332,7 @@ pub trait BlockFlowDisplayListBuilding {
state: &mut StackingContextCollectionState,
preserved_state: &mut SavedStackingContextCollectionState,
stacking_context_type: BlockStackingContextType,
can_establish_containing_block: EstablishContainingBlock)
flags: StackingContextCollectionFlags)
-> ClipAndScrollInfo;
fn setup_clip_scroll_node_for_position(&mut self,
state: &mut StackingContextCollectionState,
@ -2487,7 +2489,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
fn collect_stacking_contexts_for_block(&mut self,
state: &mut StackingContextCollectionState,
can_establish_containing_block: EstablishContainingBlock) {
flags: StackingContextCollectionFlags) {
let mut preserved_state = SavedStackingContextCollectionState::new(state);
let block_stacking_context_type = self.block_stacking_context_type();
@ -2510,10 +2512,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
self.setup_clipping_for_block(state,
&mut preserved_state,
block_stacking_context_type,
can_establish_containing_block);
flags);
if establishes_containing_block_for_absolute(can_establish_containing_block,
self.positioning()) {
if establishes_containing_block_for_absolute(flags, self.positioning()) {
state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info;
}
@ -2540,7 +2541,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
state: &mut StackingContextCollectionState,
preserved_state: &mut SavedStackingContextCollectionState,
stacking_context_type: BlockStackingContextType,
can_establish_containing_block: EstablishContainingBlock)
flags: StackingContextCollectionFlags)
-> ClipAndScrollInfo {
// If this block is absolutely positioned, we should be clipped and positioned by
// the scroll root of our nearest ancestor that establishes a containing block.
@ -2568,14 +2569,17 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
self.transform_clip_to_coordinate_space(state, preserved_state);
}
self.setup_clip_scroll_node_for_position(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_overflow(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_css_clip(state, preserved_state, &stacking_relative_border_box);
if !flags.contains(NEVER_CREATES_CLIP_SCROLL_NODE) {
self.setup_clip_scroll_node_for_position(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_overflow(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_css_clip(state, preserved_state,
&stacking_relative_border_box);
}
self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect);
// We keep track of our position so that any stickily positioned elements can
// properly determine the extent of their movement relative to scrolling containers.
if can_establish_containing_block == EstablishContainingBlock::Yes {
if !flags.contains(NEVER_CREATES_CONTAINING_BLOCK) {
let border_box = if self.fragment.establishes_stacking_context() {
stacking_relative_border_box
} else {
@ -2894,7 +2898,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
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,
if establishes_containing_block_for_absolute(StackingContextCollectionFlags::empty(),
fragment.style.get_box().position) {
state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info;
}