diff options
-rw-r--r-- | components/gfx/display_list/mod.rs | 33 | ||||
-rw-r--r-- | components/gfx/display_list/optimizer.rs | 2 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 38 | ||||
m--------- | support/android-rs-glue | 0 | ||||
-rw-r--r-- | tests/ref/basic.list | 1 | ||||
-rw-r--r-- | tests/ref/position_relative_painting_order_a.html | 28 | ||||
-rw-r--r-- | tests/ref/position_relative_painting_order_ref.html | 30 |
7 files changed, 116 insertions, 16 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 224da2ca68d..59b8d019236 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -87,8 +87,10 @@ pub struct DisplayList { pub block_backgrounds_and_borders: LinkedList<DisplayItem>, /// Floats: step 5. These are treated as pseudo-stacking contexts. pub floats: LinkedList<DisplayItem>, - /// All other content. + /// All non-positioned content. pub content: LinkedList<DisplayItem>, + /// All positioned content that does not get a stacking context. + pub positioned_content: LinkedList<DisplayItem>, /// Outlines: step 10. pub outlines: LinkedList<DisplayItem>, /// Child stacking contexts. @@ -104,6 +106,7 @@ impl DisplayList { block_backgrounds_and_borders: LinkedList::new(), floats: LinkedList::new(), content: LinkedList::new(), + positioned_content: LinkedList::new(), outlines: LinkedList::new(), children: LinkedList::new(), } @@ -117,6 +120,7 @@ impl DisplayList { self.block_backgrounds_and_borders.append(&mut other.block_backgrounds_and_borders); self.floats.append(&mut other.floats); self.content.append(&mut other.content); + self.positioned_content.append(&mut other.positioned_content); self.outlines.append(&mut other.outlines); self.children.append(&mut other.children); } @@ -125,11 +129,23 @@ impl DisplayList { #[inline] pub fn form_float_pseudo_stacking_context(&mut self) { prepend_from(&mut self.floats, &mut self.outlines); + prepend_from(&mut self.floats, &mut self.positioned_content); prepend_from(&mut self.floats, &mut self.content); prepend_from(&mut self.floats, &mut self.block_backgrounds_and_borders); prepend_from(&mut self.floats, &mut self.background_and_borders); } + /// Merges all display items from all non-positioned-content stacking levels to the + /// positioned-content stacking level. + #[inline] + pub fn form_pseudo_stacking_context_for_positioned_content(&mut self) { + prepend_from(&mut self.positioned_content, &mut self.outlines); + prepend_from(&mut self.positioned_content, &mut self.content); + prepend_from(&mut self.positioned_content, &mut self.floats); + prepend_from(&mut self.positioned_content, &mut self.block_backgrounds_and_borders); + prepend_from(&mut self.positioned_content, &mut self.background_and_borders); + } + /// Returns a list of all items in this display list concatenated together. This is extremely /// inefficient and should only be used for debugging. pub fn all_display_items(&self) -> Vec<DisplayItem> { @@ -146,6 +162,9 @@ impl DisplayList { for display_item in self.content.iter() { result.push((*display_item).clone()) } + for display_item in self.positioned_content.iter() { + result.push((*display_item).clone()) + } for display_item in self.outlines.iter() { result.push((*display_item).clone()) } @@ -215,6 +234,7 @@ impl HeapSizeOf for DisplayList { self.block_backgrounds_and_borders.heap_size_of_children() + self.floats.heap_size_of_children() + self.content.heap_size_of_children() + + self.positioned_content.heap_size_of_children() + self.outlines.heap_size_of_children() + self.children.heap_size_of_children() } @@ -359,7 +379,12 @@ impl StackingContext { display_item.draw_into_context(&mut paint_subcontext) } - // Steps 8 and 9: Positioned descendants with nonnegative z-indices. + // Step 8: Positioned descendants with `z-index: auto`. + for display_item in display_list.positioned_content.iter() { + display_item.draw_into_context(&mut paint_subcontext) + } + + // Step 9: Positioned descendants with nonnegative, numeric z-indices. for positioned_kid in positioned_children.iter() { if positioned_kid.z_index < 0 { continue @@ -513,10 +538,12 @@ impl StackingContext { } } - // Steps 7, 5, and 4: Content, floats, and block backgrounds and borders. + // Steps 8, 7, 5, and 4: Positioned content, content, floats, and block backgrounds and + // borders. // // TODO(pcwalton): Step 6: Inlines that generate stacking contexts. for display_list in [ + &self.display_list.positioned_content, &self.display_list.content, &self.display_list.floats, &self.display_list.block_backgrounds_and_borders, diff --git a/components/gfx/display_list/optimizer.rs b/components/gfx/display_list/optimizer.rs index 9306d81bbac..a16907af2c7 100644 --- a/components/gfx/display_list/optimizer.rs +++ b/components/gfx/display_list/optimizer.rs @@ -35,6 +35,8 @@ impl DisplayListOptimizer { display_list.block_backgrounds_and_borders.iter()); self.add_in_bounds_display_items(&mut result.floats, display_list.floats.iter()); self.add_in_bounds_display_items(&mut result.content, display_list.content.iter()); + self.add_in_bounds_display_items(&mut result.positioned_content, + display_list.positioned_content.iter()); self.add_in_bounds_display_items(&mut result.outlines, display_list.outlines.iter()); self.add_in_bounds_stacking_contexts(&mut result.children, display_list.children.iter()); result diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 7c4ee2b5066..a396bd543ee 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -1364,8 +1364,15 @@ impl BlockFlowDisplayListBuilding for BlockFlow { background_border_level); self.base.display_list_building_result = if self.fragment.establishes_stacking_context() { - DisplayListBuildingResult::StackingContext(self.fragment.create_stacking_context(&self.base, display_list, None)) + DisplayListBuildingResult::StackingContext( + self.fragment.create_stacking_context(&self.base, display_list, None)) } else { + match self.fragment.style.get_box().position { + position::T::static_ => {} + _ => { + display_list.form_pseudo_stacking_context_for_positioned_content(); + } + } DisplayListBuildingResult::Normal(display_list) } } @@ -1384,8 +1391,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { !self.base.flags.contains(NEEDS_LAYER) { // We didn't need a layer. self.base.display_list_building_result = - DisplayListBuildingResult::StackingContext(self.fragment - .create_stacking_context(&self.base, display_list, None)); + DisplayListBuildingResult::StackingContext( + self.fragment.create_stacking_context(&self.base, display_list, None)); return } @@ -1398,10 +1405,10 @@ impl BlockFlowDisplayListBuilding for BlockFlow { let transparent = color::transparent(); - let stacking_context = self.fragment.create_stacking_context(&self.base, display_list, - Some(Arc::new(PaintLayer::new(self.layer_id(0), - transparent, - scroll_policy)))); + let stacking_context = self.fragment.create_stacking_context( + &self.base, + display_list, + Some(Arc::new(PaintLayer::new(self.layer_id(0), transparent, scroll_policy)))); self.base.display_list_building_result = DisplayListBuildingResult::StackingContext(stacking_context) } @@ -1417,8 +1424,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { display_list.form_float_pseudo_stacking_context(); self.base.display_list_building_result = if self.fragment.establishes_stacking_context() { - DisplayListBuildingResult::StackingContext(self.fragment - .create_stacking_context(&self.base, display_list, None)) + DisplayListBuildingResult::StackingContext( + self.fragment.create_stacking_context(&self.base, display_list, None)) } else { DisplayListBuildingResult::Normal(display_list) } @@ -1496,11 +1503,16 @@ impl InlineFlowDisplayListBuilding for InlineFlow { // FIXME(Savago): fix Fragment::establishes_stacking_context() for absolute positioned item // and remove the check for filter presence. Further details on #5812. - if has_stacking_context && !self.fragments.fragments[0].style().get_effects().filter.is_empty() { + if has_stacking_context && + !self.fragments.fragments[0].style().get_effects().filter.is_empty() { self.base.display_list_building_result = - DisplayListBuildingResult::StackingContext(self.fragments.fragments[0].create_stacking_context(&self.base, display_list, None)); + DisplayListBuildingResult::StackingContext( + self.fragments.fragments[0].create_stacking_context(&self.base, + display_list, + None)); } else { - self.base.display_list_building_result = DisplayListBuildingResult::Normal(display_list); + self.base.display_list_building_result = + DisplayListBuildingResult::Normal(display_list); } if opts::get().validate_display_list_geometry { @@ -1614,7 +1626,7 @@ pub enum StackingLevel { BackgroundAndBorders, /// Borders and backgrounds for block-level descendants: step 4. BlockBackgroundsAndBorders, - /// All other content. + /// All non-positioned content. Content, } diff --git a/support/android-rs-glue b/support/android-rs-glue -Subproject dc8aef3e1b8f1acd141986cfab492e3f57d2d5f +Subproject 10116eb3af332f9565e0fb803e600511bb585d6 diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 1d322fcaa94..e91386c24ac 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -252,6 +252,7 @@ experimental != overconstrained_block.html overconstrained_block_ref.html == position_fixed_tile_edge_2.html position_fixed_tile_edge_ref.html == position_fixed_tile_edge_3.html position_fixed_tile_edge_ref.html == position_relative_a.html position_relative_b.html +== position_relative_painting_order_a.html position_relative_painting_order_ref.html == position_relative_top_percentage_a.html position_relative_top_percentage_b.html == pre_ignorable_whitespace_a.html pre_ignorable_whitespace_ref.html == pre_with_tab.html pre_with_tab_ref.html diff --git a/tests/ref/position_relative_painting_order_a.html b/tests/ref/position_relative_painting_order_a.html new file mode 100644 index 00000000000..9c8fea71e49 --- /dev/null +++ b/tests/ref/position_relative_painting_order_a.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html> +<head> +<style> +html, body { + margin: 0; +} +div { + height: 100px; + width: 100px; +} +#a { + position: relative; + top: 50px; + left: 50px; + background: purple; +} +#b { + background: steelblue; +} +</style> +</head> +<body> +<div id=a></div> +<div id=b></div> +</body> +</html> + diff --git a/tests/ref/position_relative_painting_order_ref.html b/tests/ref/position_relative_painting_order_ref.html new file mode 100644 index 00000000000..d914b18ffd2 --- /dev/null +++ b/tests/ref/position_relative_painting_order_ref.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> +<style> +html, body { + margin: 0; +} +div { + position: absolute; + height: 100px; + width: 100px; +} +#a { + top: 50px; + left: 50px; + background: purple; +} +#b { + background: steelblue; + left: 0; + top: 100px; +} +</style> +</head> +<body> +<div id=b></div> +<div id=a></div> +</body> +</html> + |