mirror of
https://github.com/servo/servo.git
synced 2025-07-25 16:20:36 +01:00
layout: Don't try to vertically align absolutely positioned children of
table rows. Improves http://reddit.com/r/aww.
This commit is contained in:
parent
781a077145
commit
18cf103ee0
4 changed files with 111 additions and 34 deletions
|
@ -12,7 +12,7 @@ use context::{LayoutContext, SharedLayoutContext};
|
||||||
use cssparser::Color;
|
use cssparser::Color;
|
||||||
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState};
|
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState};
|
||||||
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
|
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 fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
|
||||||
use gfx::display_list::StackingContext;
|
use gfx::display_list::StackingContext;
|
||||||
use gfx_traits::print_tree::PrintTree;
|
use gfx_traits::print_tree::PrintTree;
|
||||||
|
@ -81,42 +81,53 @@ impl TableCellFlow {
|
||||||
pub fn valign_children(&mut self) {
|
pub fn valign_children(&mut self) {
|
||||||
// Note to the reader: this code has been tested with negative margins.
|
// 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.
|
// 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);
|
let kid_base = flow::base(kid);
|
||||||
flow::base(kid).position.start.b
|
if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
- kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context()
|
continue
|
||||||
});
|
|
||||||
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 start = kid_base.position.start.b -
|
||||||
let self_size = flow::base(self).position.size.block -
|
kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context();
|
||||||
self.block_flow.fragment.border_padding.block_start_end();
|
let end = kid_base.position.start.b + kid_base.position.size.block +
|
||||||
let kids_self_gap = self_size - kids_size;
|
kid_base.collapsible_margins.block_end_margin_for_noncollapsible_context();
|
||||||
|
match extents {
|
||||||
// This offset should also account for vertical_align::T::baseline.
|
Some((ref mut first_start, ref mut last_end)) => {
|
||||||
// Need max cell ascent from the first row of this cell.
|
if start < *first_start {
|
||||||
let offset = match self.block_flow.fragment.style().get_box().vertical_align {
|
*first_start = start
|
||||||
vertical_align::T::middle => kids_self_gap / 2,
|
}
|
||||||
vertical_align::T::bottom => kids_self_gap,
|
if end > *last_end {
|
||||||
_ => Au(0),
|
*last_end = end
|
||||||
};
|
}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5232,6 +5232,18 @@
|
||||||
"url": "/_mozilla/css/table_valign_presentational_hint_a.html"
|
"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": [
|
"css/table_vertical_align_margin_padding.html": [
|
||||||
{
|
{
|
||||||
"path": "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"
|
"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": [
|
"css/table_vertical_align_margin_padding.html": [
|
||||||
{
|
{
|
||||||
"path": "css/table_vertical_align_margin_padding.html",
|
"path": "css/table_vertical_align_margin_padding.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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue