aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/display_list_builder.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-09-18 04:18:17 -0500
committerGitHub <noreply@github.com>2017-09-18 04:18:17 -0500
commit1da581f49b039d5eda5fa618fc41905d444c4885 (patch)
tree53a105e8e96e270ac4cd2da8dda89db029be9929 /components/layout/display_list_builder.rs
parent672eb18b64ca47f2dd2de72724319d76885dba9c (diff)
parent7429b7dcd9ef3a2b21013bd394fc369c654efbd4 (diff)
downloadservo-1da581f49b039d5eda5fa618fc41905d444c4885.tar.gz
servo-1da581f49b039d5eda5fa618fc41905d444c4885.zip
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 -->
Diffstat (limited to 'components/layout/display_list_builder.rs')
-rw-r--r--components/layout/display_list_builder.rs45
1 files changed, 26 insertions, 19 deletions
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 9c0d6449164..80665f4acbf 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 {
@@ -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;
}