Add support for vertical alignment within table cells.

Fixes #10621
This commit is contained in:
Michael Howell 2016-04-19 14:47:55 -07:00
parent f051028ee8
commit 8953207f83
9 changed files with 184 additions and 5 deletions

View file

@ -29,6 +29,10 @@ impl FlowList {
self.flows.push_back(new_tail);
}
pub fn back(&self) -> Option<&Flow> {
self.flows.back().map(|x| &**x)
}
/// Add an element first in the list
///
/// O(1)
@ -40,6 +44,10 @@ impl FlowList {
self.flows.pop_front()
}
pub fn front(&self) -> Option<&Flow> {
self.flows.front().map(|x| &**x)
}
/// Create an empty list
#[inline]
pub fn new() -> FlowList {

View file

@ -90,6 +90,14 @@ impl CollapsibleMargins {
CollapsibleMargins::CollapseThrough(ref block_start) => block_start.collapse(),
}
}
pub fn block_end_margin_for_noncollapsible_context(&self) -> Au {
match *self {
CollapsibleMargins::None(_, block_end) => block_end,
CollapsibleMargins::Collapse(_, ref block_end) |
CollapsibleMargins::CollapseThrough(ref block_end) => block_end.collapse(),
}
}
}
enum FinalMarginState {

View file

@ -12,14 +12,15 @@ use context::LayoutContext;
use cssparser::Color;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState};
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{Flow, FlowClass, OpaqueFlow};
use flow::{self, Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use incremental::REFLOW;
use layout_debug;
use model::MaybeAuto;
use std::fmt;
use std::sync::Arc;
use style::computed_values::{border_collapse, border_top_style};
use style::computed_values::{border_collapse, border_top_style, vertical_align};
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues};
use table::InternalTable;
@ -74,6 +75,42 @@ impl TableCellFlow {
None,
MarginsMayCollapseFlag::MarginsMayNotCollapse);
debug_assert!(remaining.is_none());
if !flow::base(self).restyle_damage.contains(REFLOW) {
return;
}
let first_start = flow::base(self).children.front().map(|kid| {
flow::base(kid).position.start.b
});
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;
}
}
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;
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;
}
}
}
}
}

View file

@ -1,3 +0,0 @@
[vertical-align-applies-to-007.htm]
type: reftest
expected: FAIL

View file

@ -5791,6 +5791,30 @@
"url": "/_mozilla/mozilla/sslfail.html"
}
],
"mozilla/table_valign_bottom.html": [
{
"path": "mozilla/table_valign_bottom.html",
"references": [
[
"/_mozilla/mozilla/table_valign_bottom_ref.html",
"=="
]
],
"url": "/_mozilla/mozilla/table_valign_bottom.html"
}
],
"mozilla/table_valign_middle.html": [
{
"path": "mozilla/table_valign_middle.html",
"references": [
[
"/_mozilla/mozilla/table_valign_middle_ref.html",
"=="
]
],
"url": "/_mozilla/mozilla/table_valign_middle.html"
}
],
"mozilla/webgl/clearcolor.html": [
{
"path": "mozilla/webgl/clearcolor.html",
@ -12465,6 +12489,30 @@
"url": "/_mozilla/mozilla/sslfail.html"
}
],
"mozilla/table_valign_bottom.html": [
{
"path": "mozilla/table_valign_bottom.html",
"references": [
[
"/_mozilla/mozilla/table_valign_bottom_ref.html",
"=="
]
],
"url": "/_mozilla/mozilla/table_valign_bottom.html"
}
],
"mozilla/table_valign_middle.html": [
{
"path": "mozilla/table_valign_middle.html",
"references": [
[
"/_mozilla/mozilla/table_valign_middle_ref.html",
"=="
]
],
"url": "/_mozilla/mozilla/table_valign_middle.html"
}
],
"mozilla/webgl/clearcolor.html": [
{
"path": "mozilla/webgl/clearcolor.html",

View file

@ -0,0 +1,17 @@
<!doctype html>
<meta charset="utf-8">
<title>Table align bottom</title>
<link rel="match" href="table_valign_bottom_ref.html">
<style>
td {
height: 5em;
width: 5em;
border: 1px solid black;
vertical-align: bottom;
}
</style>
<table>
<tr>
<td>Foo</td>
</tr>
</table>

View file

@ -0,0 +1,25 @@
<!doctype html>
<meta charset="utf-8">
<title>Reference: table align bottom</title>
<style>
td {
height: 5em;
width: 5em;
border: 1px solid black;
}
div {
position: relative;
height: 5em;
width: 5em;
}
span {
position: absolute;
bottom: 0;
}
</style>
<table>
<tr>
<td><div><span>Foo</span></div></td>
</tr>
</table>

View file

@ -0,0 +1,16 @@
<!doctype html>
<meta charset="utf-8">
<title>Middle alignment in tables</title>
<link rel="match" href="table_valign_middle_ref.html">
<style>
td {
height: 5em;
width: 5em;
border: 1px solid black;
}
</style>
<table>
<tr>
<td>Foo</td>
</tr>
</table>

View file

@ -0,0 +1,23 @@
<!doctype html>
<meta charset="utf-8">
<title>Reference: middle alignment in tables</title>
<style>
td {
height: 5em;
width: 5em;
border: 1px solid black;
vertical-align: top;
}
div {
width: 5em;
height: 5em;
line-height: 5em;
vertical-align: middle;
}
</style>
<table>
<tr>
<td><div>Foo</div></td>
</tr>
</table>