mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #18506 - mrobinson:position-sticky-table, r=emilio
Fix issues with the combination of position:sticky and tables <!-- 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 - [ ] These changes fix #18441 (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. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18506) <!-- Reviewable:end -->
This commit is contained in:
commit
1da581f49b
11 changed files with 81 additions and 33 deletions
|
@ -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 {
|
||||
|
@ -2346,16 +2345,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,
|
||||
|
@ -2364,7 +2366,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,
|
||||
|
@ -2521,7 +2523,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();
|
||||
|
@ -2544,10 +2546,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;
|
||||
}
|
||||
|
||||
|
@ -2574,7 +2575,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.
|
||||
|
@ -2602,14 +2603,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 {
|
||||
|
@ -2678,6 +2682,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
|
||||
let new_clip_scroll_node_id = ClipId::new(self.fragment.unique_id(IdType::OverflowClip),
|
||||
state.pipeline_id.to_webrender());
|
||||
if state.has_clip_scroll_node(new_clip_scroll_node_id) {
|
||||
return;
|
||||
}
|
||||
let parent_id = self.clip_and_scroll_info(state.pipeline_id).scroll_node_id;
|
||||
state.add_clip_scroll_node(
|
||||
ClipScrollNode {
|
||||
|
@ -2928,7 +2935,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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue