mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
layout: Draw elements with position: relative; z-index: auto
over
ordinary content per CSS 2.1 Appendix E. Improves Talking Points Memo.
This commit is contained in:
parent
234fb68a16
commit
87a620e1b3
7 changed files with 117 additions and 17 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit dc8aef3e1b8f1acd141986cfab492e3f57d2d5f6
|
||||
Subproject commit 10116eb3af332f9565e0fb803e600511bb585d6b
|
|
@ -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
|
||||
|
|
28
tests/ref/position_relative_painting_order_a.html
Normal file
28
tests/ref/position_relative_painting_order_a.html
Normal file
|
@ -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>
|
||||
|
30
tests/ref/position_relative_painting_order_ref.html
Normal file
30
tests/ref/position_relative_painting_order_ref.html
Normal file
|
@ -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>
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue