diff options
author | Martin Robinson <mrobinson@igalia.com> | 2017-08-24 09:37:49 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2017-09-05 09:10:55 +0200 |
commit | bc455c8a1f5f355323c63e5d1639df2fcaaba5df (patch) | |
tree | 8cbe1bfbe8145242736759ed39c1cdd8b42eb683 /components/layout | |
parent | 4725a05bfba0b588d19af8bc5cfe960bda1ea880 (diff) | |
download | servo-bc455c8a1f5f355323c63e5d1639df2fcaaba5df.tar.gz servo-bc455c8a1f5f355323c63e5d1639df2fcaaba5df.zip |
Add support for position:sticky
This leverages the position:sticky support in WebRender to bring basic
support for position:sticky in Servo. There are still some issues with
nested sticky flows as well as a few other corner cases. Tests are
imported from WPT and can be removed once we update to the latest
version.
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/block.rs | 26 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 151 | ||||
-rw-r--r-- | components/layout/fragment.rs | 5 | ||||
-rw-r--r-- | components/layout/query.rs | 3 | ||||
-rw-r--r-- | components/layout/sequential.rs | 2 | ||||
-rw-r--r-- | components/layout/table.rs | 5 | ||||
-rw-r--r-- | components/layout/table_caption.rs | 5 | ||||
-rw-r--r-- | components/layout/table_cell.rs | 5 | ||||
-rw-r--r-- | components/layout/table_row.rs | 5 | ||||
-rw-r--r-- | components/layout/table_rowgroup.rs | 5 | ||||
-rw-r--r-- | components/layout/table_wrapper.rs | 5 | ||||
-rw-r--r-- | components/layout/webrender_helpers.rs | 6 |
12 files changed, 176 insertions, 47 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index b22519ee71a..b0bb0c9b671 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -29,9 +29,9 @@ use app_units::{Au, MAX_AU}; use context::LayoutContext; -use display_list_builder::{BorderPaintingMode, DisplayListBuildState}; -use display_list_builder::BlockFlowDisplayListBuilding; -use euclid::{Point2D, Size2D, Rect}; +use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; +use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; +use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use floats::{ClearType, FloatKind, Floats, PlacementInfo}; use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag}; use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT}; @@ -54,7 +54,7 @@ use std::sync::Arc; use style::computed_values::{border_collapse, box_sizing, display, float, overflow_x}; use style::computed_values::{position, text_align}; use style::context::SharedStyleContext; -use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; +use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use style::properties::ComputedValues; use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW}; use style::values::computed::{LengthOrPercentageOrNone, LengthOrPercentage}; @@ -643,7 +643,7 @@ impl BlockFlow { &mut self.fragment } - pub fn stacking_relative_position(&self, coor: CoordinateSystem) -> Rect<Au> { + pub fn stacking_relative_border_box(&self, coor: CoordinateSystem) -> Rect<Au> { return self.fragment.stacking_relative_border_box( &self.base.stacking_relative_position, &self.base.early_absolute_position_info.relative_containing_block_size, @@ -1787,6 +1787,20 @@ impl BlockFlow { self.flags.contains(HAS_SCROLLING_OVERFLOW) } + // Return offset from original position because of `position: sticky`. + pub fn sticky_position(&self) -> SideOffsets2D<MaybeAuto> { + let containing_block_size = &self.base.early_absolute_position_info + .relative_containing_block_size; + let writing_mode = self.base.early_absolute_position_info.relative_containing_block_mode; + let offsets = self.fragment.style().logical_position(); + let as_margins = LogicalMargin::new(writing_mode, + MaybeAuto::from_style(offsets.block_start, containing_block_size.inline), + MaybeAuto::from_style(offsets.inline_end, containing_block_size.inline), + MaybeAuto::from_style(offsets.block_end, containing_block_size.inline), + MaybeAuto::from_style(offsets.inline_start, containing_block_size.inline)); + as_margins.to_physical(writing_mode) + } + } impl Flow for BlockFlow { @@ -2134,7 +2148,7 @@ impl Flow for BlockFlow { } fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { - self.collect_stacking_contexts_for_block(state); + self.collect_stacking_contexts_for_block(state, EstablishContainingBlock::Yes); } 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 e7f4474e8f6..6387c72ce3d 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -14,7 +14,8 @@ use app_units::{AU_PER_PX, Au}; use block::{BlockFlow, BlockStackingContextType}; use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg}; use context::LayoutContext; -use euclid::{Transform3D, Point2D, Vector2D, Rect, SideOffsets2D, Size2D, TypedSize2D}; +use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, TypedSize2D}; +use euclid::Vector2D; use flex::FlexFlow; use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED}; use flow_ref::FlowRef; @@ -72,7 +73,8 @@ use style_traits::ToCss; use style_traits::cursor::Cursor; use table_cell::CollapsedBordersForCell; use webrender_api::{ClipAndScrollInfo, ClipId, ColorF, ComplexClipRegion, GradientStop, LineStyle}; -use webrender_api::{LocalClip, RepeatMode, ScrollPolicy, ScrollSensitivity}; +use webrender_api::{LocalClip, RepeatMode, ScrollPolicy, ScrollSensitivity, StickyFrameInfo}; +use webrender_api::StickySideConstraint; use webrender_helpers::{ToBorderRadius, ToMixBlendMode, ToRectF, ToTransformStyle}; trait ResolvePercentage { @@ -101,11 +103,11 @@ fn convert_repeat_mode(from: RepeatKeyword) -> RepeatMode { } } -fn establishes_containing_block_for_absolute(positioning: position::T) -> bool { - match positioning { - position::T::absolute | position::T::relative | position::T::fixed => true, - _ => false, - } +fn establishes_containing_block_for_absolute(can_establish_containing_block: EstablishContainingBlock, + positioning: position::T) + -> bool { + can_establish_containing_block == EstablishContainingBlock::Yes && + position::T::static_ != positioning } trait RgbColor { @@ -192,6 +194,9 @@ pub struct DisplayListBuildState<'a> { /// A stack of clips used to cull display list entries that are outside the /// rendered region, but only collected at containing block boundaries. pub containing_block_clip_stack: Vec<Rect<Au>>, + + /// The flow parent's content box, used to calculate sticky constraints. + parent_stacking_relative_content_box: Rect<Au>, } impl<'a> DisplayListBuildState<'a> { @@ -211,6 +216,7 @@ impl<'a> DisplayListBuildState<'a> { iframe_sizes: Vec::new(), clip_stack: Vec::new(), containing_block_clip_stack: Vec::new(), + parent_stacking_relative_content_box: Rect::zero(), } } @@ -2254,8 +2260,16 @@ impl FragmentDisplayListBuilding for Fragment { } } +#[derive(Clone, Copy, PartialEq)] +pub enum EstablishContainingBlock { + Yes, + No, +} + pub trait BlockFlowDisplayListBuilding { - fn collect_stacking_contexts_for_block(&mut self, state: &mut DisplayListBuildState); + fn collect_stacking_contexts_for_block(&mut self, + state: &mut DisplayListBuildState, + can_establish_containing_block: EstablishContainingBlock); fn transform_clip_to_coordinate_space(&mut self, state: &mut DisplayListBuildState, @@ -2263,8 +2277,12 @@ pub trait BlockFlowDisplayListBuilding { fn setup_clipping_for_block(&mut self, state: &mut DisplayListBuildState, preserved_state: &mut PreservedDisplayListState, - stacking_context_type: BlockStackingContextType) + stacking_context_type: BlockStackingContextType, + can_establish_containing_block: EstablishContainingBlock) -> ClipAndScrollInfo; + fn setup_scroll_root_for_position(&mut self, + state: &mut DisplayListBuildState, + border_box: &Rect<Au>); fn setup_scroll_root_for_overflow(&mut self, state: &mut DisplayListBuildState, border_box: &Rect<Au>); @@ -2297,6 +2315,7 @@ pub struct PreservedDisplayListState { containing_block_clip_and_scroll_info: ClipAndScrollInfo, clips_pushed: usize, containing_block_clips_pushed: usize, + stacking_relative_content_box: Rect<Au>, } impl PreservedDisplayListState { @@ -2308,6 +2327,7 @@ impl PreservedDisplayListState { containing_block_clip_and_scroll_info: state.containing_block_clip_and_scroll_info, clips_pushed: 0, containing_block_clips_pushed: 0, + stacking_relative_content_box: state.parent_stacking_relative_content_box, } } @@ -2322,6 +2342,7 @@ impl PreservedDisplayListState { state.current_real_stacking_context_id = self.real_stacking_context_id; state.current_clip_and_scroll_info = self.clip_and_scroll_info; state.containing_block_clip_and_scroll_info = self.containing_block_clip_and_scroll_info; + state.parent_stacking_relative_content_box = self.stacking_relative_content_box; let truncate_length = state.clip_stack.len() - self.clips_pushed; state.clip_stack.truncate(truncate_length); @@ -2359,7 +2380,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { if state.clip_stack.is_empty() { return; } - let border_box = self.stacking_relative_position(CoordinateSystem::Parent); + let border_box = self.stacking_relative_border_box(CoordinateSystem::Parent); let transform = match self.fragment.transform_matrix(&border_box) { Some(transform) => transform, None => return, @@ -2412,7 +2433,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } } - fn collect_stacking_contexts_for_block(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts_for_block(&mut self, + state: &mut DisplayListBuildState, + can_establish_containing_block: EstablishContainingBlock) { let mut preserved_state = PreservedDisplayListState::new(state); let block_stacking_context_type = self.block_stacking_context_type(); @@ -2432,8 +2455,13 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // stored in state.current_clip_and_scroll_info. If we create a stacking context, // we don't want it to be contained by its own scroll root. let containing_clip_and_scroll_info = - self.setup_clipping_for_block(state, &mut preserved_state, block_stacking_context_type); - if establishes_containing_block_for_absolute(self.positioning()) { + self.setup_clipping_for_block(state, + &mut preserved_state, + block_stacking_context_type, + can_establish_containing_block); + + if establishes_containing_block_for_absolute(can_establish_containing_block, + self.positioning()) { state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info; } @@ -2459,7 +2487,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { fn setup_clipping_for_block(&mut self, state: &mut DisplayListBuildState, preserved_state: &mut PreservedDisplayListState, - stacking_context_type: BlockStackingContextType) + stacking_context_type: BlockStackingContextType, + can_establish_containing_block: EstablishContainingBlock) -> 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. @@ -2477,26 +2506,33 @@ impl BlockFlowDisplayListBuilding for BlockFlow { }; self.base.clip_and_scroll_info = Some(containing_clip_and_scroll_info); - let coordinate_system = if self.fragment.establishes_stacking_context() { - CoordinateSystem::Own + let stacking_relative_border_box = if self.fragment.establishes_stacking_context() { + self.stacking_relative_border_box(CoordinateSystem::Own) } else { - CoordinateSystem::Parent + self.stacking_relative_border_box(CoordinateSystem::Parent) }; - let stacking_relative_border_box = self.fragment.stacking_relative_border_box( - &self.base.stacking_relative_position, - &self.base.early_absolute_position_info.relative_containing_block_size, - self.base.early_absolute_position_info.relative_containing_block_mode, - coordinate_system); - if stacking_context_type == BlockStackingContextType::StackingContext { self.transform_clip_to_coordinate_space(state, preserved_state); } + self.setup_scroll_root_for_position(state, &stacking_relative_border_box); self.setup_scroll_root_for_overflow(state, &stacking_relative_border_box); self.setup_scroll_root_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 { + let border_box = if self.fragment.establishes_stacking_context() { + stacking_relative_border_box + } else { + self.stacking_relative_border_box(CoordinateSystem::Own) + }; + state.parent_stacking_relative_content_box = + self.fragment.stacking_relative_content_box(&border_box) + } + match self.positioning() { position::T::absolute | position::T::relative | position::T::fixed => state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info, @@ -2506,6 +2542,72 @@ impl BlockFlowDisplayListBuilding for BlockFlow { containing_clip_and_scroll_info } + fn setup_scroll_root_for_position(&mut self, + state: &mut DisplayListBuildState, + border_box: &Rect<Au>) { + if self.positioning() != position::T::sticky { + return; + } + + let sticky_position = self.sticky_position(); + if sticky_position.left == MaybeAuto::Auto && sticky_position.right == MaybeAuto::Auto && + sticky_position.top == MaybeAuto::Auto && sticky_position.bottom == MaybeAuto::Auto { + return; + } + + // Since position: sticky elements always establish a stacking context, we will + // have previously calculated our border box in our own coordinate system. In + // order to properly calculate max offsets we need to compare our size and + // position in our parent's coordinate system. + let border_box_in_parent = self.stacking_relative_border_box(CoordinateSystem::Parent); + let margins = self.fragment.margin.to_physical( + self.base.early_absolute_position_info.relative_containing_block_mode); + + // Position:sticky elements are always restricted based on the size and position of + // their containing block, which for sticky items is like relative and statically + // positioned items: just the parent block. + let constraint_rect = state.parent_stacking_relative_content_box; + + let to_max_offset = |constraint_edge: Au, moving_edge: Au| -> f32 { + (constraint_edge - moving_edge).to_f32_px() + }; + + let to_sticky_info = |margin: MaybeAuto, max_offset: f32| -> Option<StickySideConstraint> { + match margin { + MaybeAuto::Auto => None, + MaybeAuto::Specified(value) => + Some(StickySideConstraint { margin: value.to_f32_px(), max_offset }), + } + }; + + let sticky_frame_info = StickyFrameInfo::new( + to_sticky_info(sticky_position.top, + to_max_offset(constraint_rect.max_y(), border_box_in_parent.max_y())), + to_sticky_info(sticky_position.right, + to_max_offset(constraint_rect.min_x(), border_box_in_parent.min_x() - margins.left)), + to_sticky_info(sticky_position.bottom, + to_max_offset(constraint_rect.min_y(), border_box_in_parent.min_y() - margins.top)), + to_sticky_info(sticky_position.left, + to_max_offset(constraint_rect.max_x(), border_box_in_parent.max_x()))); + + let new_scroll_root_id = ClipId::new(self.fragment.unique_id(IdType::OverflowClip), + state.layout_context.id.to_webrender()); + let parent_id = self.clip_and_scroll_info(state.layout_context.id).scroll_node_id; + state.add_scroll_root( + ScrollRoot { + id: new_scroll_root_id, + parent_id: parent_id, + clip: ClippingRegion::from_rect(border_box), + content_rect: Rect::zero(), + root_type: ScrollRootType::StickyFrame(sticky_frame_info), + }, + ); + + let new_clip_and_scroll_info = ClipAndScrollInfo::simple(new_scroll_root_id); + self.base.clip_and_scroll_info = Some(new_clip_and_scroll_info); + state.current_clip_and_scroll_info = new_clip_and_scroll_info; + } + fn setup_scroll_root_for_overflow(&mut self, state: &mut DisplayListBuildState, border_box: &Rect<Au>) { @@ -2737,7 +2839,8 @@ 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(fragment.style.get_box().position) { + if establishes_containing_block_for_absolute(EstablishContainingBlock::Yes, + fragment.style.get_box().position) { state.containing_block_clip_and_scroll_info = state.current_clip_and_scroll_info; } diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 4e0763612ad..8cd37f314ed 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -2521,8 +2521,9 @@ impl Fragment { return true } - // Fixed position blocks always create stacking contexts. - if self.style.get_box().position == position::T::fixed { + // Fixed position and sticky position always create stacking contexts. + if self.style().get_box().position == position::T::fixed || + self.style().get_box().position == position::T::sticky { return true } diff --git a/components/layout/query.rs b/components/layout/query.rs index 5803a247e19..f3040376f60 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -598,6 +598,7 @@ impl FragmentBorderBoxIterator for ParentOffsetBorderBoxIterator { (true, _, _) | (false, computed_values::position::T::static_, &SpecificFragmentInfo::Table) | (false, computed_values::position::T::static_, &SpecificFragmentInfo::TableCell) | + (false, computed_values::position::T::sticky, _) | (false, computed_values::position::T::absolute, _) | (false, computed_values::position::T::relative, _) | (false, computed_values::position::T::fixed, _) => true, @@ -766,7 +767,7 @@ where let positioned = match style.get_box().position { position::computed_value::T::relative | - /*position::computed_value::T::sticky |*/ + position::computed_value::T::sticky | position::computed_value::T::fixed | position::computed_value::T::absolute => true, _ => false diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 3c95b75fbb6..1121ace2d89 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -95,7 +95,7 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut Flow, iterator flow::base(kid).stacking_relative_position + stacking_context_position.to_vector(); let relative_position = kid.as_block() - .stacking_relative_position(CoordinateSystem::Own); + .stacking_relative_border_box(CoordinateSystem::Own); if let Some(matrix) = kid.as_block() .fragment .transform_matrix(&relative_position) { diff --git a/components/layout/table.rs b/components/layout/table.rs index b56ac7c4d09..974a497bb94 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -10,7 +10,8 @@ use app_units::Au; use block::{BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer}; use block::{ISizeConstraintInput, ISizeConstraintSolution}; use context::LayoutContext; -use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState}; +use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; +use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; use euclid::Point2D; use flow; use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; @@ -503,7 +504,7 @@ impl Flow for TableFlow { } fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { - self.block_flow.collect_stacking_contexts(state); + self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::Yes); } fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 8e5fa302028..39e20d95bbf 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -9,7 +9,8 @@ use app_units::Au; use block::BlockFlow; use context::LayoutContext; -use display_list_builder::DisplayListBuildState; +use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState}; +use display_list_builder::EstablishContainingBlock; use euclid::Point2D; use flow::{Flow, FlowClass, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; @@ -80,7 +81,7 @@ impl Flow for TableCaptionFlow { } fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { - self.block_flow.collect_stacking_contexts(state); + self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 370937bc73d..389232345f6 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -9,7 +9,8 @@ use app_units::Au; use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag}; use context::LayoutContext; -use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState}; +use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; +use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; @@ -260,7 +261,7 @@ impl Flow for TableCellFlow { } fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { - self.block_flow.collect_stacking_contexts(state); + self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 3e6365d8c77..070e7da9229 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -9,7 +9,8 @@ use app_units::Au; use block::{BlockFlow, ISizeAndMarginsComputer}; use context::LayoutContext; -use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState}; +use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; +use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; use euclid::Point2D; use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; use flow_list::MutFlowListIterator; @@ -478,7 +479,7 @@ impl Flow for TableRowFlow { } fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { - self.block_flow.collect_stacking_contexts(state); + self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 760a20a72fc..c3cb764686b 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -9,7 +9,8 @@ use app_units::Au; use block::{BlockFlow, ISizeAndMarginsComputer}; use context::LayoutContext; -use display_list_builder::DisplayListBuildState; +use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState}; +use display_list_builder::EstablishContainingBlock; use euclid::Point2D; use flow::{Flow, FlowClass, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; @@ -183,7 +184,7 @@ impl Flow for TableRowGroupFlow { } fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { - self.block_flow.collect_stacking_contexts(state); + self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 531176d52d3..5619a487ea7 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -17,7 +17,8 @@ use app_units::Au; use block::{AbsoluteNonReplaced, BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput}; use block::{ISizeConstraintSolution, MarginsMayCollapseFlag}; use context::LayoutContext; -use display_list_builder::DisplayListBuildState; +use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState}; +use display_list_builder::EstablishContainingBlock; use euclid::Point2D; use floats::FloatKind; use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow}; @@ -463,7 +464,7 @@ impl Flow for TableWrapperFlow { } fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { - self.block_flow.collect_stacking_contexts(state); + self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) { diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs index 6e5a774e283..6370043542f 100644 --- a/components/layout/webrender_helpers.rs +++ b/components/layout/webrender_helpers.rs @@ -493,10 +493,11 @@ impl WebRenderDisplayItemConverter for DisplayItem { builder.push_clip_id(item.scroll_root.parent_id); let our_id = item.scroll_root.id; + let item_rect = item.scroll_root.clip.main.to_rectf(); let webrender_id = match item.scroll_root.root_type { ScrollRootType::Clip => { builder.define_clip(Some(our_id), - item.scroll_root.clip.main.to_rectf(), + item_rect, item.scroll_root.clip.get_complex_clips(), None) } @@ -508,6 +509,9 @@ impl WebRenderDisplayItemConverter for DisplayItem { None, scroll_sensitivity) } + ScrollRootType::StickyFrame(sticky_frame_info) => { + builder.define_sticky_frame(Some(our_id), item_rect, sticky_frame_info) + } }; debug_assert!(our_id == webrender_id); |