aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/block.rs4
-rw-r--r--components/layout/display_list_builder.rs42
-rw-r--r--components/layout/table.rs5
-rw-r--r--components/layout/table_caption.rs5
-rw-r--r--components/layout/table_cell.rs5
-rw-r--r--components/layout/table_row.rs5
-rw-r--r--components/layout/table_rowgroup.rs4
-rw-r--r--components/layout/table_wrapper.rs6
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json25
-rw-r--r--tests/wpt/mozilla/tests/css/table_with_position_sticky.html7
-rw-r--r--tests/wpt/mozilla/tests/css/table_with_position_sticky_ref.html3
11 files changed, 78 insertions, 33 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 6ecf6bc77c1..86e540b111a 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -30,7 +30,7 @@
use app_units::{Au, MAX_AU};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
-use display_list_builder::{DisplayListBuildState, EstablishContainingBlock};
+use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags};
use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
@@ -2152,7 +2152,7 @@ impl Flow for BlockFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
- self.collect_stacking_contexts_for_block(state, EstablishContainingBlock::Yes);
+ self.collect_stacking_contexts_for_block(state, StackingContextCollectionFlags::empty());
}
fn build_display_list(&mut self, state: &mut DisplayListBuildState) {
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;
}
diff --git a/components/layout/table.rs b/components/layout/table.rs
index e373385e050..713249cf145 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -11,7 +11,7 @@ use block::{BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer};
use block::{ISizeConstraintInput, ISizeConstraintSolution};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
-use display_list_builder::{DisplayListBuildState, EstablishContainingBlock};
+use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags};
use display_list_builder::StackingContextCollectionState;
use euclid::Point2D;
use flow;
@@ -505,7 +505,8 @@ impl Flow for TableFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
- self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::Yes);
+ self.block_flow.collect_stacking_contexts_for_block(state,
+ StackingContextCollectionFlags::empty());
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs
index 2ee55382f6c..ecdd52784ee 100644
--- a/components/layout/table_caption.rs
+++ b/components/layout/table_caption.rs
@@ -10,7 +10,7 @@ use app_units::Au;
use block::BlockFlow;
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState};
-use display_list_builder::{EstablishContainingBlock, StackingContextCollectionState};
+use display_list_builder::{StackingContextCollectionFlags, StackingContextCollectionState};
use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
@@ -81,7 +81,8 @@ impl Flow for TableCaptionFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
- self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No);
+ self.block_flow.collect_stacking_contexts_for_block(state,
+ StackingContextCollectionFlags::empty());
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 42dfce82cff..1c04b327904 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -10,7 +10,7 @@ use app_units::Au;
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
-use display_list_builder::{DisplayListBuildState, EstablishContainingBlock};
+use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags};
use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow};
@@ -263,7 +263,8 @@ impl Flow for TableCellFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
- self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No);
+ self.block_flow.collect_stacking_contexts_for_block(state,
+ StackingContextCollectionFlags::empty());
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 17728a5ae0b..e7ec462ca20 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -10,7 +10,7 @@ use app_units::Au;
use block::{BlockFlow, ISizeAndMarginsComputer};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
-use display_list_builder::{DisplayListBuildState, EstablishContainingBlock};
+use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags};
use display_list_builder::StackingContextCollectionState;
use euclid::Point2D;
use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
@@ -480,7 +480,8 @@ impl Flow for TableRowFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
- self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No);
+ self.block_flow.collect_stacking_contexts_for_block(state,
+ StackingContextCollectionFlags::empty());
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index aabc56b8e54..ee596d45525 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -10,7 +10,7 @@ use app_units::Au;
use block::{BlockFlow, ISizeAndMarginsComputer};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState};
-use display_list_builder::{EstablishContainingBlock, StackingContextCollectionState};
+use display_list_builder::{NEVER_CREATES_CONTAINING_BLOCK, StackingContextCollectionState};
use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
@@ -184,7 +184,7 @@ impl Flow for TableRowGroupFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
- self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No);
+ self.block_flow.collect_stacking_contexts_for_block(state, NEVER_CREATES_CONTAINING_BLOCK);
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index 1d9c2f6566e..972f5299094 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -18,7 +18,8 @@ use block::{AbsoluteNonReplaced, BlockFlow, FloatNonReplaced, ISizeAndMarginsCom
use block::{ISizeConstraintSolution, MarginsMayCollapseFlag};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState};
-use display_list_builder::{EstablishContainingBlock, StackingContextCollectionState};
+use display_list_builder::{NEVER_CREATES_CLIP_SCROLL_NODE, NEVER_CREATES_CONTAINING_BLOCK};
+use display_list_builder::StackingContextCollectionState;
use euclid::Point2D;
use floats::FloatKind;
use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow};
@@ -458,7 +459,8 @@ impl Flow for TableWrapperFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
- self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No);
+ self.block_flow.collect_stacking_contexts_for_block(
+ state, NEVER_CREATES_CONTAINING_BLOCK | NEVER_CREATES_CLIP_SCROLL_NODE);
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 433cfa07a89..2c0e62850ba 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -5921,6 +5921,18 @@
{}
]
],
+ "css/table_with_position_sticky.html": [
+ [
+ "/_mozilla/css/table_with_position_sticky.html",
+ [
+ [
+ "/_mozilla/css/table_with_position_sticky_ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"css/text_align_complex_a.html": [
[
"/_mozilla/css/text_align_complex_a.html",
@@ -10367,6 +10379,11 @@
{}
]
],
+ "css/table_with_position_sticky_ref.html": [
+ [
+ {}
+ ]
+ ],
"css/test.jpeg": [
[
{}
@@ -26589,6 +26606,14 @@
"0dc40b30f1d518d7c148535d9230a95417aadd56",
"support"
],
+ "css/table_with_position_sticky.html": [
+ "30c4f54f51c8d35614d52d3702e58de8589acd2f",
+ "reftest"
+ ],
+ "css/table_with_position_sticky_ref.html": [
+ "da028fde51bd53b7c7a4314e998162ab10d8d359",
+ "support"
+ ],
"css/test.jpeg": [
"b7329039658f91906338b4ec599633f966de1b46",
"support"
diff --git a/tests/wpt/mozilla/tests/css/table_with_position_sticky.html b/tests/wpt/mozilla/tests/css/table_with_position_sticky.html
new file mode 100644
index 00000000000..327f668ec30
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/table_with_position_sticky.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<title>Tables with position:sticky elements should not cause a panic</title>
+<link rel="match" href="table_with_position_sticky_ref.html" />
+<link rel="help" href="https://www.w3.org/TR/css-position-3/#sticky-pos" />
+<meta name="assert" content="This test checks that tables with position:sticky dont' cause a panic" />
+<div style="width: 100px; height: 100px; background: green"></div>
+<table style="position: sticky; top: 0;">
diff --git a/tests/wpt/mozilla/tests/css/table_with_position_sticky_ref.html b/tests/wpt/mozilla/tests/css/table_with_position_sticky_ref.html
new file mode 100644
index 00000000000..e7e5d66cd23
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/table_with_position_sticky_ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<title>Reference for Tables with position:sticky elements should not cause a panic</title>
+<div style="width: 100px; height: 100px; background: green"></div>