diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2016-10-12 16:54:12 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2016-10-13 14:52:10 -0700 |
commit | 18cf103ee02c9473da004849b8fd18c7f5fb68f3 (patch) | |
tree | fe1c7f55bbf16f590ec65b401c5ea5c2ffb9a8b5 | |
parent | 781a0771458de73d2f843377082a6961c38fb66d (diff) | |
download | servo-18cf103ee02c9473da004849b8fd18c7f5fb68f3.tar.gz servo-18cf103ee02c9473da004849b8fd18c7f5fb68f3.zip |
layout: Don't try to vertically align absolutely positioned children of
table rows.
Improves http://reddit.com/r/aww.
-rw-r--r-- | components/layout/table_cell.rs | 79 | ||||
-rw-r--r-- | tests/wpt/mozilla/meta/MANIFEST.json | 24 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/css/table_vertical_align_absolute_a.html | 24 | ||||
-rw-r--r-- | tests/wpt/mozilla/tests/css/table_vertical_align_absolute_ref.html | 18 |
4 files changed, 111 insertions, 34 deletions
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index a1f1eab101a..62d5608023d 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -12,7 +12,7 @@ use context::{LayoutContext, SharedLayoutContext}; use cssparser::Color; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; -use flow::{self, Flow, FlowClass, OpaqueFlow}; +use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; use gfx::display_list::StackingContext; use gfx_traits::print_tree::PrintTree; @@ -81,42 +81,53 @@ impl TableCellFlow { pub fn valign_children(&mut self) { // Note to the reader: this code has been tested with negative margins. // We end up with a "end" that's before the "start," but the math still works out. - let first_start = flow::base(self).children.front().map(|kid| { + let mut extents = None; + for kid in flow::base(self).children.iter() { let kid_base = flow::base(kid); - flow::base(kid).position.start.b - - kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context() - }); - if let Some(mut first_start) = first_start { - let mut last_end = first_start; - for kid in flow::base(self).children.iter() { - let kid_base = flow::base(kid); - let start = kid_base.position.start.b - - kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context(); - let end = kid_base.position.start.b + kid_base.position.size.block - + kid_base.collapsible_margins.block_end_margin_for_noncollapsible_context(); - if start < first_start { - first_start = start; - } - if end > last_end { - last_end = end; - } + if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) { + continue } - let kids_size = last_end - first_start; - let self_size = flow::base(self).position.size.block - - self.block_flow.fragment.border_padding.block_start_end(); - let kids_self_gap = self_size - kids_size; - - // This offset should also account for vertical_align::T::baseline. - // Need max cell ascent from the first row of this cell. - let offset = match self.block_flow.fragment.style().get_box().vertical_align { - vertical_align::T::middle => kids_self_gap / 2, - vertical_align::T::bottom => kids_self_gap, - _ => Au(0), - }; - if offset != Au(0) { - for kid in flow::mut_base(self).children.iter_mut() { - flow::mut_base(kid).position.start.b = flow::mut_base(kid).position.start.b + offset; + let start = kid_base.position.start.b - + kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context(); + let end = kid_base.position.start.b + kid_base.position.size.block + + kid_base.collapsible_margins.block_end_margin_for_noncollapsible_context(); + match extents { + Some((ref mut first_start, ref mut last_end)) => { + if start < *first_start { + *first_start = start + } + if end > *last_end { + *last_end = end + } } + None => extents = Some((start, end)), + } + } + let (first_start, last_end) = match extents { + Some(extents) => extents, + None => return, + }; + + let kids_size = last_end - first_start; + let self_size = flow::base(self).position.size.block - + self.block_flow.fragment.border_padding.block_start_end(); + let kids_self_gap = self_size - kids_size; + + // This offset should also account for vertical_align::T::baseline. + // Need max cell ascent from the first row of this cell. + let offset = match self.block_flow.fragment.style().get_box().vertical_align { + vertical_align::T::middle => kids_self_gap / 2, + vertical_align::T::bottom => kids_self_gap, + _ => Au(0), + }; + if offset == Au(0) { + return + } + + for kid in flow::mut_base(self).children.iter_mut() { + let mut kid_base = flow::mut_base(kid); + if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) { + kid_base.position.start.b += offset } } } diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 49ffeb63737..7884fab4632 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -5232,6 +5232,18 @@ "url": "/_mozilla/css/table_valign_presentational_hint_a.html" } ], + "css/table_vertical_align_absolute_a.html": [ + { + "path": "css/table_vertical_align_absolute_a.html", + "references": [ + [ + "/_mozilla/css/table_vertical_align_absolute_ref.html", + "==" + ] + ], + "url": "/_mozilla/css/table_vertical_align_absolute_a.html" + } + ], "css/table_vertical_align_margin_padding.html": [ { "path": "css/table_vertical_align_margin_padding.html", @@ -19038,6 +19050,18 @@ "url": "/_mozilla/css/table_valign_presentational_hint_ref.html" } ], + "css/table_vertical_align_absolute_a.html": [ + { + "path": "css/table_vertical_align_absolute_a.html", + "references": [ + [ + "/_mozilla/css/table_vertical_align_absolute_ref.html", + "==" + ] + ], + "url": "/_mozilla/css/table_vertical_align_absolute_a.html" + } + ], "css/table_vertical_align_margin_padding.html": [ { "path": "css/table_vertical_align_margin_padding.html", diff --git a/tests/wpt/mozilla/tests/css/table_vertical_align_absolute_a.html b/tests/wpt/mozilla/tests/css/table_vertical_align_absolute_a.html new file mode 100644 index 00000000000..d29bbca479c --- /dev/null +++ b/tests/wpt/mozilla/tests/css/table_vertical_align_absolute_a.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="match" href="table_vertical_align_absolute_ref.html"> +<style> +body, html { + margin: 0; +} +tr { + vertical-align: bottom; + height: 300px; +} +tr::after { + content: ""; + display: block; + position: absolute; + background: blue; + top: 0; + left: 0; + width: 100px; + height: 100px; +} +</style> +<table><tr><td> + diff --git a/tests/wpt/mozilla/tests/css/table_vertical_align_absolute_ref.html b/tests/wpt/mozilla/tests/css/table_vertical_align_absolute_ref.html new file mode 100644 index 00000000000..908fccbfdc2 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/table_vertical_align_absolute_ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<style> +body, html { + margin: 0; +} +div { + position: absolute; + background: blue; + top: 0; + left: 0; + width: 100px; + height: 100px; +} +</style> +<div> + + |