diff options
9 files changed, 72 insertions, 42 deletions
diff --git a/components/gfx_traits/lib.rs b/components/gfx_traits/lib.rs index 9688d90bbef..6f5b380dd43 100644 --- a/components/gfx_traits/lib.rs +++ b/components/gfx_traits/lib.rs @@ -42,10 +42,9 @@ impl StackingContextId { StackingContextId(0) } - /// Returns a new sacking context id with the given numeric id. - #[inline] - pub fn new(id: u64) -> StackingContextId { - StackingContextId(id) + pub fn next(&self) -> StackingContextId { + let StackingContextId(id) = *self; + StackingContextId(id + 1) } } diff --git a/components/layout/block.rs b/components/layout/block.rs index bffcbef0e67..aaad1d51937 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -1670,20 +1670,6 @@ impl BlockFlow { self.base.flags = flags } - pub fn block_stacking_context_type(&self) -> BlockStackingContextType { - if self.fragment.establishes_stacking_context() { - return BlockStackingContextType::StackingContext - } - - if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) || - self.fragment.style.get_box().position != position::T::static_ || - self.base.flags.is_float() { - BlockStackingContextType::PseudoStackingContext - } else { - BlockStackingContextType::NonstackingContext - } - } - pub fn overflow_style_may_require_clip_scroll_node(&self) -> bool { match (self.fragment.style().get_box().overflow_x, self.fragment.style().get_box().overflow_y) { diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index d478bdd3694..170b662662c 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -181,6 +181,9 @@ pub struct StackingContextCollectionState { /// The current stacking real context id, which doesn't include pseudo-stacking contexts. pub current_real_stacking_context_id: StackingContextId, + /// The next stacking context id that we will assign to a stacking context. + pub next_stacking_context_id: StackingContextId, + /// The current clip and scroll info, used to keep track of state when /// recursively building and processing the display list. pub current_clip_and_scroll_info: ClipAndScrollInfo, @@ -212,6 +215,7 @@ impl StackingContextCollectionState { clip_scroll_node_parents: FnvHashMap::default(), current_stacking_context_id: StackingContextId::root(), current_real_stacking_context_id: StackingContextId::root(), + next_stacking_context_id: StackingContextId::root().next(), current_clip_and_scroll_info: root_clip_info, containing_block_clip_and_scroll_info: root_clip_info, clip_stack: Vec::new(), @@ -220,6 +224,11 @@ impl StackingContextCollectionState { } } + fn generate_stacking_context_id(&mut self) -> StackingContextId { + let next_stacking_context_id = self.next_stacking_context_id.next(); + mem::replace(&mut self.next_stacking_context_id, next_stacking_context_id) + } + fn add_stacking_context(&mut self, parent_id: StackingContextId, stacking_context: StackingContext) { @@ -611,10 +620,6 @@ pub trait FragmentDisplayListBuilding { parent_clip_and_scroll_info: ClipAndScrollInfo) -> StackingContext; - - /// The id of stacking context this fragment would create. - fn stacking_context_id(&self) -> StackingContextId; - fn unique_id(&self, id_type: IdType) -> u64; fn fragment_type(&self) -> FragmentType; @@ -2169,10 +2174,6 @@ impl FragmentDisplayListBuilding for Fragment { } } - fn stacking_context_id(&self) -> StackingContextId { - StackingContextId::new(self.unique_id(IdType::StackingContext)) - } - fn create_stacking_context(&self, id: StackingContextId, base_flow: &BaseFlow, @@ -2394,9 +2395,11 @@ impl FragmentDisplayListBuilding for Fragment { bitflags! { pub flags StackingContextCollectionFlags: u8 { /// This flow never establishes a containing block. - const NEVER_CREATES_CONTAINING_BLOCK = 0x01, + const NEVER_CREATES_CONTAINING_BLOCK = 0b001, /// This flow never creates a ClipScrollNode. - const NEVER_CREATES_CLIP_SCROLL_NODE = 0x02, + const NEVER_CREATES_CLIP_SCROLL_NODE = 0b010, + /// This flow never creates a stacking context. + const NEVER_CREATES_STACKING_CONTEXT = 0b100, } } @@ -2435,6 +2438,11 @@ pub trait BlockFlowDisplayListBuilding { fn build_display_list_for_block(&mut self, state: &mut DisplayListBuildState, border_painting_mode: BorderPaintingMode); + + fn block_stacking_context_type( + &self, + flags: StackingContextCollectionFlags, + ) -> BlockStackingContextType; } /// This structure manages ensuring that modification to StackingContextCollectionState is @@ -2572,11 +2580,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { flags: StackingContextCollectionFlags) { let mut preserved_state = SavedStackingContextCollectionState::new(state); - let block_stacking_context_type = self.block_stacking_context_type(); + let block_stacking_context_type = self.block_stacking_context_type(flags); self.base.stacking_context_id = match block_stacking_context_type { BlockStackingContextType::NonstackingContext => state.current_stacking_context_id, BlockStackingContextType::PseudoStackingContext | - BlockStackingContextType::StackingContext => self.fragment.stacking_context_id(), + BlockStackingContextType::StackingContext => state.generate_stacking_context_id(), }; state.current_stacking_context_id = self.base.stacking_context_id; @@ -2963,6 +2971,33 @@ impl BlockFlowDisplayListBuilding for BlockFlow { state.processing_scrolling_overflow_element = false; } + #[inline] + fn block_stacking_context_type( + &self, + flags: StackingContextCollectionFlags, + ) -> BlockStackingContextType { + if flags.contains(NEVER_CREATES_STACKING_CONTEXT) { + return BlockStackingContextType::NonstackingContext; + } + + if self.fragment.establishes_stacking_context() { + return BlockStackingContextType::StackingContext + } + + if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { + return BlockStackingContextType::PseudoStackingContext + } + + if self.fragment.style.get_box().position != position::T::static_ { + return BlockStackingContextType::PseudoStackingContext + } + + if self.base.flags.is_float() { + return BlockStackingContextType::PseudoStackingContext + } + + BlockStackingContextType::NonstackingContext + } } pub trait InlineFlowDisplayListBuilding { @@ -2988,7 +3023,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow { if !fragment.collect_stacking_contexts_for_blocklike_fragment(state) { if fragment.establishes_stacking_context() { - fragment.stacking_context_id = fragment.stacking_context_id(); + fragment.stacking_context_id = state.generate_stacking_context_id(); let current_stacking_context_id = state.current_stacking_context_id; let stacking_context = diff --git a/components/layout/table.rs b/components/layout/table.rs index 7009e4ec60b..37fb246935f 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, StackingContextCollectionFlags}; +use display_list_builder::{DisplayListBuildState, NEVER_CREATES_STACKING_CONTEXT}; use display_list_builder::StackingContextCollectionState; use euclid::Point2D; use flow; @@ -504,8 +504,8 @@ impl Flow for TableFlow { } fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { - self.block_flow.collect_stacking_contexts_for_block(state, - StackingContextCollectionFlags::empty()); + // Stacking contexts are collected by the table wrapper. + self.block_flow.collect_stacking_contexts_for_block(state, NEVER_CREATES_STACKING_CONTEXT); } fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { diff --git a/components/style/stylist.rs b/components/style/stylist.rs index e40c1a7c842..72445369d7c 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -763,13 +763,21 @@ impl Stylist { // For most (but not all) pseudo-elements, we inherit all values from the parent. let inherit_all = match *pseudo { + // Anonymous table flows shouldn't inherit their parents properties in order + // to avoid doubling up styles such as transformations. + PseudoElement::ServoAnonymousTableCell | + PseudoElement::ServoAnonymousTableRow | PseudoElement::ServoText | PseudoElement::ServoInputText => false, PseudoElement::ServoAnonymousBlock | + + // For tables, we do want style to inherit, because TableWrapper is responsible + // for handling clipping and scrolling, while Table is responsible for creating + // stacking contexts. StackingContextCollectionFlags makes sure this is processed + // properly. PseudoElement::ServoAnonymousTable | - PseudoElement::ServoAnonymousTableCell | - PseudoElement::ServoAnonymousTableRow | PseudoElement::ServoAnonymousTableWrapper | + PseudoElement::ServoTableWrapper | PseudoElement::ServoInlineBlockWrapper | PseudoElement::ServoInlineAbsolute => true, diff --git a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-table-002.htm.ini b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-table-002.htm.ini new file mode 100644 index 00000000000..7a0e1e2fac8 --- /dev/null +++ b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-table-002.htm.ini @@ -0,0 +1,4 @@ +[transform-table-002.htm] + type: reftest + expected: FAIL + bug: https://github.com/servo/servo/issues/8003 diff --git a/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-table-005.htm.ini b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-table-005.htm.ini new file mode 100644 index 00000000000..1e3a14cf667 --- /dev/null +++ b/tests/wpt/metadata-css/css-transforms-1_dev/html/transform-table-005.htm.ini @@ -0,0 +1,4 @@ +[transform-table-005.htm] + type: reftest + expected: FAIL + bug: https://github.com/servo/servo/issues/8003 diff --git a/tests/wpt/metadata-css/css21_dev/html4/abspos-containing-block-initial-005b.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abspos-containing-block-initial-005b.htm.ini deleted file mode 100644 index 02c3f7ec9dd..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abspos-containing-block-initial-005b.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abspos-containing-block-initial-005b.htm] - type: reftest - expected: FAIL diff --git a/tests/wpt/metadata-css/css21_dev/html4/abspos-containing-block-initial-005d.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/abspos-containing-block-initial-005d.htm.ini deleted file mode 100644 index 087e871ddf4..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/abspos-containing-block-initial-005d.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[abspos-containing-block-initial-005d.htm] - type: reftest - expected: FAIL |