diff options
author | Martin Robinson <mrobinson@igalia.com> | 2017-09-14 12:19:50 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2017-09-15 15:55:56 +0200 |
commit | f1596e83a9ede7ad17ce9c51aa04912e82fb9b5c (patch) | |
tree | 04922d5327e7b61904a190ddee9bf49b9c8c43f1 /components/layout/display_list_builder.rs | |
parent | 89d5780570894a54774542e79585b79ece3f2dce (diff) | |
download | servo-f1596e83a9ede7ad17ce9c51aa04912e82fb9b5c.tar.gz servo-f1596e83a9ede7ad17ce9c51aa04912e82fb9b5c.zip |
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.
Diffstat (limited to 'components/layout/display_list_builder.rs')
-rw-r--r-- | components/layout/display_list_builder.rs | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 4379de6e6e4..187799e6f76 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -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; } |