aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2016-10-12 16:54:12 -0700
committerPatrick Walton <pcwalton@mimiga.net>2016-10-13 14:52:10 -0700
commit18cf103ee02c9473da004849b8fd18c7f5fb68f3 (patch)
treefe1c7f55bbf16f590ec65b401c5ea5c2ffb9a8b5
parent781a0771458de73d2f843377082a6961c38fb66d (diff)
downloadservo-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.rs79
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json24
-rw-r--r--tests/wpt/mozilla/tests/css/table_vertical_align_absolute_a.html24
-rw-r--r--tests/wpt/mozilla/tests/css/table_vertical_align_absolute_ref.html18
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>
+
+