mirror of
https://github.com/servo/servo.git
synced 2025-06-24 09:04:33 +01:00
layout: Make margin: auto
work properly with tables.
Improves the Amazon home page.
This commit is contained in:
parent
ae99a17a1b
commit
44a30054a1
9 changed files with 246 additions and 98 deletions
|
@ -622,51 +622,44 @@ impl BlockFlow {
|
||||||
/// Compute the actual inline size and position for this block.
|
/// Compute the actual inline size and position for this block.
|
||||||
pub fn compute_used_inline_size(&mut self,
|
pub fn compute_used_inline_size(&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
containing_block_inline_size: Au,
|
containing_block_inline_size: Au) {
|
||||||
border_collapse: border_collapse::T) {
|
|
||||||
let block_type = self.block_type();
|
let block_type = self.block_type();
|
||||||
match block_type {
|
match block_type {
|
||||||
BlockType::AbsoluteReplaced => {
|
BlockType::AbsoluteReplaced => {
|
||||||
let inline_size_computer = AbsoluteReplaced;
|
let inline_size_computer = AbsoluteReplaced;
|
||||||
inline_size_computer.compute_used_inline_size(self,
|
inline_size_computer.compute_used_inline_size(self,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
}
|
}
|
||||||
BlockType::AbsoluteNonReplaced => {
|
BlockType::AbsoluteNonReplaced => {
|
||||||
let inline_size_computer = AbsoluteNonReplaced;
|
let inline_size_computer = AbsoluteNonReplaced;
|
||||||
inline_size_computer.compute_used_inline_size(self,
|
inline_size_computer.compute_used_inline_size(self,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
}
|
}
|
||||||
BlockType::FloatReplaced => {
|
BlockType::FloatReplaced => {
|
||||||
let inline_size_computer = FloatReplaced;
|
let inline_size_computer = FloatReplaced;
|
||||||
inline_size_computer.compute_used_inline_size(self,
|
inline_size_computer.compute_used_inline_size(self,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
}
|
}
|
||||||
BlockType::FloatNonReplaced => {
|
BlockType::FloatNonReplaced => {
|
||||||
let inline_size_computer = FloatNonReplaced;
|
let inline_size_computer = FloatNonReplaced;
|
||||||
inline_size_computer.compute_used_inline_size(self,
|
inline_size_computer.compute_used_inline_size(self,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
}
|
}
|
||||||
BlockType::Replaced => {
|
BlockType::Replaced => {
|
||||||
let inline_size_computer = BlockReplaced;
|
let inline_size_computer = BlockReplaced;
|
||||||
inline_size_computer.compute_used_inline_size(self,
|
inline_size_computer.compute_used_inline_size(self,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
}
|
}
|
||||||
BlockType::NonReplaced => {
|
BlockType::NonReplaced => {
|
||||||
let inline_size_computer = BlockNonReplaced;
|
let inline_size_computer = BlockNonReplaced;
|
||||||
inline_size_computer.compute_used_inline_size(self,
|
inline_size_computer.compute_used_inline_size(self,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1201,13 +1194,9 @@ impl BlockFlow {
|
||||||
/// Compute inline size based using the `block_container_inline_size` set by the parent flow.
|
/// Compute inline size based using the `block_container_inline_size` set by the parent flow.
|
||||||
///
|
///
|
||||||
/// This is run in the `AssignISizes` traversal.
|
/// This is run in the `AssignISizes` traversal.
|
||||||
fn propagate_and_compute_used_inline_size(&mut self,
|
fn propagate_and_compute_used_inline_size(&mut self, layout_context: &LayoutContext) {
|
||||||
layout_context: &LayoutContext,
|
|
||||||
border_collapse: border_collapse::T) {
|
|
||||||
let containing_block_inline_size = self.base.block_container_inline_size;
|
let containing_block_inline_size = self.base.block_container_inline_size;
|
||||||
self.compute_used_inline_size(layout_context,
|
self.compute_used_inline_size(layout_context, containing_block_inline_size);
|
||||||
containing_block_inline_size,
|
|
||||||
border_collapse);
|
|
||||||
if self.base.flags.is_float() {
|
if self.base.flags.is_float() {
|
||||||
self.float.as_mut().unwrap().containing_inline_size = containing_block_inline_size
|
self.float.as_mut().unwrap().containing_inline_size = containing_block_inline_size
|
||||||
}
|
}
|
||||||
|
@ -1589,8 +1578,7 @@ impl Flow for BlockFlow {
|
||||||
|
|
||||||
// Our inline-size was set to the inline-size of the containing block by the flow's parent.
|
// Our inline-size was set to the inline-size of the containing block by the flow's parent.
|
||||||
// Now compute the real value.
|
// Now compute the real value.
|
||||||
let border_collapse = self.fragment.style.get_inheritedtable().border_collapse;
|
self.propagate_and_compute_used_inline_size(layout_context);
|
||||||
self.propagate_and_compute_used_inline_size(layout_context, border_collapse);
|
|
||||||
|
|
||||||
// Formatting contexts are never impacted by floats.
|
// Formatting contexts are never impacted by floats.
|
||||||
match self.formatting_context_type() {
|
match self.formatting_context_type() {
|
||||||
|
@ -2041,6 +2029,12 @@ impl ISizeConstraintSolution {
|
||||||
//
|
//
|
||||||
// CSS Section 10.3
|
// CSS Section 10.3
|
||||||
pub trait ISizeAndMarginsComputer {
|
pub trait ISizeAndMarginsComputer {
|
||||||
|
/// Instructs the fragment to compute its border and padding.
|
||||||
|
fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) {
|
||||||
|
block.fragment.compute_border_and_padding(containing_block_inline_size,
|
||||||
|
border_collapse::T::separate);
|
||||||
|
}
|
||||||
|
|
||||||
/// Compute the inputs for the ISize constraint equation.
|
/// Compute the inputs for the ISize constraint equation.
|
||||||
///
|
///
|
||||||
/// This is called only once to compute the initial inputs. For calculations involving
|
/// This is called only once to compute the initial inputs. For calculations involving
|
||||||
|
@ -2048,15 +2042,14 @@ pub trait ISizeAndMarginsComputer {
|
||||||
fn compute_inline_size_constraint_inputs(&self,
|
fn compute_inline_size_constraint_inputs(&self,
|
||||||
block: &mut BlockFlow,
|
block: &mut BlockFlow,
|
||||||
parent_flow_inline_size: Au,
|
parent_flow_inline_size: Au,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext)
|
||||||
border_collapse: border_collapse::T)
|
|
||||||
-> ISizeConstraintInput {
|
-> ISizeConstraintInput {
|
||||||
let containing_block_inline_size =
|
let containing_block_inline_size =
|
||||||
self.containing_block_inline_size(block, parent_flow_inline_size, layout_context);
|
self.containing_block_inline_size(block, parent_flow_inline_size, layout_context);
|
||||||
|
|
||||||
block.fragment.compute_block_direction_margins(containing_block_inline_size);
|
block.fragment.compute_block_direction_margins(containing_block_inline_size);
|
||||||
block.fragment.compute_inline_direction_margins(containing_block_inline_size);
|
block.fragment.compute_inline_direction_margins(containing_block_inline_size);
|
||||||
block.fragment.compute_border_and_padding(containing_block_inline_size, border_collapse);
|
self.compute_border_and_padding(block, containing_block_inline_size);
|
||||||
|
|
||||||
let mut computed_inline_size = self.initial_computed_inline_size(block,
|
let mut computed_inline_size = self.initial_computed_inline_size(block,
|
||||||
parent_flow_inline_size,
|
parent_flow_inline_size,
|
||||||
|
@ -2183,12 +2176,10 @@ pub trait ISizeAndMarginsComputer {
|
||||||
fn compute_used_inline_size(&self,
|
fn compute_used_inline_size(&self,
|
||||||
block: &mut BlockFlow,
|
block: &mut BlockFlow,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
parent_flow_inline_size: Au,
|
parent_flow_inline_size: Au) {
|
||||||
border_collapse: border_collapse::T) {
|
|
||||||
let mut input = self.compute_inline_size_constraint_inputs(block,
|
let mut input = self.compute_inline_size_constraint_inputs(block,
|
||||||
parent_flow_inline_size,
|
parent_flow_inline_size,
|
||||||
layout_context,
|
layout_context);
|
||||||
border_collapse);
|
|
||||||
|
|
||||||
let containing_block_inline_size =
|
let containing_block_inline_size =
|
||||||
self.containing_block_inline_size(block, parent_flow_inline_size, layout_context);
|
self.containing_block_inline_size(block, parent_flow_inline_size, layout_context);
|
||||||
|
|
|
@ -424,12 +424,12 @@ impl Flow for TableFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let inline_size_computer = InternalTable;
|
let inline_size_computer = InternalTable {
|
||||||
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse;
|
border_collapse: self.block_flow.fragment.style.get_inheritedtable().border_collapse,
|
||||||
|
};
|
||||||
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
|
|
||||||
let inline_start_content_edge = self.block_flow.fragment.border_padding.inline_start;
|
let inline_start_content_edge = self.block_flow.fragment.border_padding.inline_start;
|
||||||
let inline_end_content_edge = self.block_flow.fragment.border_padding.inline_end;
|
let inline_end_content_edge = self.block_flow.fragment.border_padding.inline_end;
|
||||||
|
@ -581,21 +581,26 @@ impl fmt::Debug for TableFlow {
|
||||||
|
|
||||||
/// Table, TableRowGroup, TableRow, TableCell types.
|
/// Table, TableRowGroup, TableRow, TableCell types.
|
||||||
/// Their inline-sizes are calculated in the same way and do not have margins.
|
/// Their inline-sizes are calculated in the same way and do not have margins.
|
||||||
pub struct InternalTable;
|
pub struct InternalTable {
|
||||||
|
pub border_collapse: border_collapse::T,
|
||||||
|
}
|
||||||
|
|
||||||
impl ISizeAndMarginsComputer for InternalTable {
|
impl ISizeAndMarginsComputer for InternalTable {
|
||||||
|
fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) {
|
||||||
|
block.fragment.compute_border_and_padding(containing_block_inline_size,
|
||||||
|
self.border_collapse)
|
||||||
|
}
|
||||||
|
|
||||||
/// Compute the used value of inline-size, taking care of min-inline-size and max-inline-size.
|
/// Compute the used value of inline-size, taking care of min-inline-size and max-inline-size.
|
||||||
///
|
///
|
||||||
/// CSS Section 10.4: Minimum and Maximum inline-sizes
|
/// CSS Section 10.4: Minimum and Maximum inline-sizes
|
||||||
fn compute_used_inline_size(&self,
|
fn compute_used_inline_size(&self,
|
||||||
block: &mut BlockFlow,
|
block: &mut BlockFlow,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
parent_flow_inline_size: Au,
|
parent_flow_inline_size: Au) {
|
||||||
border_collapse: border_collapse::T) {
|
|
||||||
let input = self.compute_inline_size_constraint_inputs(block,
|
let input = self.compute_inline_size_constraint_inputs(block,
|
||||||
parent_flow_inline_size,
|
parent_flow_inline_size,
|
||||||
layout_context,
|
layout_context);
|
||||||
border_collapse);
|
|
||||||
let solution = self.solve_inline_size_constraints(block, &input);
|
let solution = self.solve_inline_size_constraints(block, &input);
|
||||||
|
|
||||||
self.set_inline_size_constraint_solutions(block, solution);
|
self.set_inline_size_constraint_solutions(block, solution);
|
||||||
|
@ -603,7 +608,7 @@ impl ISizeAndMarginsComputer for InternalTable {
|
||||||
|
|
||||||
/// Solve the inline-size and margins constraints for this block flow.
|
/// Solve the inline-size and margins constraints for this block flow.
|
||||||
fn solve_inline_size_constraints(&self, _: &mut BlockFlow, input: &ISizeConstraintInput)
|
fn solve_inline_size_constraints(&self, _: &mut BlockFlow, input: &ISizeConstraintInput)
|
||||||
-> ISizeConstraintSolution {
|
-> ISizeConstraintSolution {
|
||||||
ISizeConstraintSolution::new(input.available_inline_size, Au(0), Au(0))
|
ISizeConstraintSolution::new(input.available_inline_size, Au(0), Au(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,12 +135,12 @@ impl Flow for TableCellFlow {
|
||||||
// The position was set to the column inline-size by the parent flow, table row flow.
|
// The position was set to the column inline-size by the parent flow, table row flow.
|
||||||
let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
|
let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
|
||||||
|
|
||||||
let inline_size_computer = InternalTable;
|
let inline_size_computer = InternalTable {
|
||||||
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse;
|
border_collapse: self.block_flow.fragment.style.get_inheritedtable().border_collapse,
|
||||||
|
};
|
||||||
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
|
|
||||||
let inline_start_content_edge =
|
let inline_start_content_edge =
|
||||||
self.block_flow.fragment.border_box.start.i +
|
self.block_flow.fragment.border_box.start.i +
|
||||||
|
|
|
@ -311,12 +311,12 @@ impl Flow for TableRowFlow {
|
||||||
let inline_start_content_edge = Au(0);
|
let inline_start_content_edge = Au(0);
|
||||||
let inline_end_content_edge = Au(0);
|
let inline_end_content_edge = Au(0);
|
||||||
|
|
||||||
let inline_size_computer = InternalTable;
|
let inline_size_computer = InternalTable {
|
||||||
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse;
|
border_collapse: self.block_flow.fragment.style.get_inheritedtable().border_collapse,
|
||||||
|
};
|
||||||
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
|
|
||||||
// Spread out the completed inline sizes among columns with spans > 1.
|
// Spread out the completed inline sizes among columns with spans > 1.
|
||||||
let mut computed_inline_size_for_cells = Vec::new();
|
let mut computed_inline_size_for_cells = Vec::new();
|
||||||
|
|
|
@ -151,12 +151,13 @@ impl Flow for TableRowGroupFlow {
|
||||||
let (inline_start_content_edge, inline_end_content_edge) = (Au(0), Au(0));
|
let (inline_start_content_edge, inline_end_content_edge) = (Au(0), Au(0));
|
||||||
let content_inline_size = containing_block_inline_size;
|
let content_inline_size = containing_block_inline_size;
|
||||||
|
|
||||||
let inline_size_computer = InternalTable;
|
|
||||||
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse;
|
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse;
|
||||||
|
let inline_size_computer = InternalTable {
|
||||||
|
border_collapse: border_collapse,
|
||||||
|
};
|
||||||
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
inline_size_computer.compute_used_inline_size(&mut self.block_flow,
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block_inline_size,
|
containing_block_inline_size);
|
||||||
border_collapse);
|
|
||||||
|
|
||||||
let column_computed_inline_sizes = &self.column_computed_inline_sizes;
|
let column_computed_inline_sizes = &self.column_computed_inline_sizes;
|
||||||
let border_spacing = self.spacing;
|
let border_spacing = self.spacing;
|
||||||
|
|
|
@ -13,13 +13,14 @@
|
||||||
|
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
use block::{BlockFlow, BlockNonReplaced, FloatNonReplaced, ISizeAndMarginsComputer};
|
use block::{BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput};
|
||||||
use block::{MarginsMayCollapseFlag};
|
use block::{ISizeConstraintSolution, MarginsMayCollapseFlag};
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use floats::FloatKind;
|
use floats::FloatKind;
|
||||||
use flow::{FlowClass, Flow, ImmutableFlowUtils};
|
use flow::{FlowClass, Flow, ImmutableFlowUtils};
|
||||||
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
|
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
|
||||||
use fragment::{Fragment, FragmentBorderBoxIterator};
|
use fragment::{Fragment, FragmentBorderBoxIterator};
|
||||||
|
use model::MaybeAuto;
|
||||||
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
|
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
|
||||||
use table_row;
|
use table_row;
|
||||||
use wrapper::ThreadSafeLayoutNode;
|
use wrapper::ThreadSafeLayoutNode;
|
||||||
|
@ -31,7 +32,7 @@ use std::cmp::{max, min};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use style::computed_values::table_layout;
|
use style::computed_values::{border_collapse, table_layout};
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::CSSFloat;
|
use style::values::CSSFloat;
|
||||||
use style::values::computed::LengthOrPercentageOrAuto;
|
use style::values::computed::LengthOrPercentageOrAuto;
|
||||||
|
@ -55,8 +56,7 @@ pub struct TableWrapperFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TableWrapperFlow {
|
impl TableWrapperFlow {
|
||||||
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
|
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment)
|
||||||
fragment: Fragment)
|
|
||||||
-> TableWrapperFlow {
|
-> TableWrapperFlow {
|
||||||
let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
|
let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
|
||||||
let table_layout = if block_flow.fragment().style().get_table().table_layout ==
|
let table_layout = if block_flow.fragment().style().get_table().table_layout ==
|
||||||
|
@ -90,6 +90,21 @@ impl TableWrapperFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn border_padding_and_spacing(&mut self) -> (Au, Au) {
|
||||||
|
let (mut table_border_padding, mut spacing) = (Au(0), Au(0));
|
||||||
|
for kid in self.block_flow.base.child_iter() {
|
||||||
|
if kid.is_table() {
|
||||||
|
let kid_table = kid.as_table();
|
||||||
|
let spacing_per_cell = kid_table.spacing().horizontal;
|
||||||
|
spacing = spacing_per_cell * (self.column_intrinsic_inline_sizes.len() as i32 + 1);
|
||||||
|
table_border_padding =
|
||||||
|
kid_table.block_flow.fragment.border_padding.inline_start_end();
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(table_border_padding, spacing)
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculates table column sizes for automatic layout per INTRINSIC § 4.3.
|
/// Calculates table column sizes for automatic layout per INTRINSIC § 4.3.
|
||||||
fn calculate_table_column_sizes_for_automatic_layout(
|
fn calculate_table_column_sizes_for_automatic_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -100,20 +115,13 @@ impl TableWrapperFlow {
|
||||||
// when normally the child computes it itself. But it has to be this way because the
|
// when normally the child computes it itself. But it has to be this way because the
|
||||||
// padding will affect where we place the child. This is an odd artifact of the way that
|
// padding will affect where we place the child. This is an odd artifact of the way that
|
||||||
// tables are separated into table flows and table wrapper flows.
|
// tables are separated into table flows and table wrapper flows.
|
||||||
//
|
let available_inline_size = self.block_flow.fragment.border_box.size.inline;
|
||||||
// FIXME(pcwalton): Handle `border-collapse` correctly.
|
|
||||||
let mut available_inline_size = self.block_flow.fragment.border_box.size.inline;
|
|
||||||
let (mut table_border_padding, mut spacing) = (Au(0), Au(0));
|
|
||||||
for kid in self.block_flow.base.child_iter() {
|
for kid in self.block_flow.base.child_iter() {
|
||||||
if !kid.is_table() {
|
if !kid.is_table() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let kid_table = kid.as_table();
|
let kid_table = kid.as_table();
|
||||||
let spacing_per_cell = kid_table.spacing().horizontal;
|
|
||||||
spacing = spacing_per_cell * (self.column_intrinsic_inline_sizes.len() as i32 + 1);
|
|
||||||
available_inline_size = self.block_flow.fragment.border_box.size.inline;
|
|
||||||
|
|
||||||
let kid_block_flow = &mut kid_table.block_flow;
|
let kid_block_flow = &mut kid_table.block_flow;
|
||||||
kid_block_flow.fragment
|
kid_block_flow.fragment
|
||||||
.compute_border_and_padding(available_inline_size,
|
.compute_border_and_padding(available_inline_size,
|
||||||
|
@ -124,10 +132,11 @@ impl TableWrapperFlow {
|
||||||
.border_collapse);
|
.border_collapse);
|
||||||
kid_block_flow.fragment.compute_block_direction_margins(available_inline_size);
|
kid_block_flow.fragment.compute_block_direction_margins(available_inline_size);
|
||||||
kid_block_flow.fragment.compute_inline_direction_margins(available_inline_size);
|
kid_block_flow.fragment.compute_inline_direction_margins(available_inline_size);
|
||||||
table_border_padding = kid_block_flow.fragment.border_padding.inline_start_end();
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (table_border_padding, spacing) = self.border_padding_and_spacing();
|
||||||
|
|
||||||
// FIXME(pcwalton, spec): INTRINSIC § 8 does not properly define how to compute this, but
|
// FIXME(pcwalton, spec): INTRINSIC § 8 does not properly define how to compute this, but
|
||||||
// says "the basic idea is the same as the shrink-to-fit width that CSS2.1 defines". So we
|
// says "the basic idea is the same as the shrink-to-fit width that CSS2.1 defines". So we
|
||||||
// just use the shrink-to-fit inline size.
|
// just use the shrink-to-fit inline size.
|
||||||
|
@ -201,37 +210,55 @@ impl TableWrapperFlow {
|
||||||
table_border_padding + spacing + self.block_flow.fragment.margin.inline_start_end();
|
table_border_padding + spacing + self.block_flow.fragment.margin.inline_start_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_used_inline_size(&mut self,
|
fn compute_used_inline_size(
|
||||||
layout_context: &LayoutContext,
|
&mut self,
|
||||||
parent_flow_inline_size: Au) {
|
layout_context: &LayoutContext,
|
||||||
// Delegate to the appropriate inline size computer to find the constraint inputs.
|
parent_flow_inline_size: Au,
|
||||||
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse;
|
intermediate_column_inline_sizes: &[IntermediateColumnInlineSize]) {
|
||||||
let input = if self.block_flow.base.flags.is_float() {
|
let (border_padding, spacing) = self.border_padding_and_spacing();
|
||||||
FloatNonReplaced.compute_inline_size_constraint_inputs(&mut self.block_flow,
|
let minimum_width_of_all_columns =
|
||||||
parent_flow_inline_size,
|
intermediate_column_inline_sizes.iter()
|
||||||
layout_context,
|
.fold(border_padding + spacing,
|
||||||
border_collapse)
|
|accumulator, intermediate_column_inline_sizes| {
|
||||||
} else {
|
accumulator + intermediate_column_inline_sizes.size
|
||||||
BlockNonReplaced.compute_inline_size_constraint_inputs(&mut self.block_flow,
|
});
|
||||||
parent_flow_inline_size,
|
|
||||||
layout_context,
|
|
||||||
border_collapse)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delegate to the appropriate inline size computer to write the constraint solutions in.
|
// Delegate to the appropriate inline size computer to find the constraint inputs and write
|
||||||
|
// the constraint solutions in.
|
||||||
|
let border_collapse = self.block_flow.fragment.style.get_inheritedtable().border_collapse;
|
||||||
if self.block_flow.base.flags.is_float() {
|
if self.block_flow.base.flags.is_float() {
|
||||||
let solution = FloatNonReplaced.solve_inline_size_constraints(&mut self.block_flow,
|
let inline_size_computer = FloatedTable {
|
||||||
&input);
|
minimum_width_of_all_columns: minimum_width_of_all_columns,
|
||||||
FloatNonReplaced.set_inline_size_constraint_solutions(&mut self.block_flow, solution);
|
border_collapse: border_collapse,
|
||||||
FloatNonReplaced.set_inline_position_of_flow_if_necessary(&mut self.block_flow,
|
};
|
||||||
solution);
|
let input =
|
||||||
} else {
|
inline_size_computer.compute_inline_size_constraint_inputs(&mut self.block_flow,
|
||||||
let solution = BlockNonReplaced.solve_inline_size_constraints(&mut self.block_flow,
|
parent_flow_inline_size,
|
||||||
&input);
|
layout_context);
|
||||||
BlockNonReplaced.set_inline_size_constraint_solutions(&mut self.block_flow, solution);
|
|
||||||
BlockNonReplaced.set_inline_position_of_flow_if_necessary(&mut self.block_flow,
|
let solution = inline_size_computer.solve_inline_size_constraints(&mut self.block_flow,
|
||||||
|
&input);
|
||||||
|
inline_size_computer.set_inline_size_constraint_solutions(&mut self.block_flow,
|
||||||
solution);
|
solution);
|
||||||
|
inline_size_computer.set_inline_position_of_flow_if_necessary(&mut self.block_flow,
|
||||||
|
solution);
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inline_size_computer = Table {
|
||||||
|
minimum_width_of_all_columns: minimum_width_of_all_columns,
|
||||||
|
border_collapse: border_collapse,
|
||||||
|
};
|
||||||
|
let input =
|
||||||
|
inline_size_computer.compute_inline_size_constraint_inputs(&mut self.block_flow,
|
||||||
|
parent_flow_inline_size,
|
||||||
|
layout_context);
|
||||||
|
|
||||||
|
let solution = inline_size_computer.solve_inline_size_constraints(&mut self.block_flow,
|
||||||
|
&input);
|
||||||
|
inline_size_computer.set_inline_size_constraint_solutions(&mut self.block_flow, solution);
|
||||||
|
inline_size_computer.set_inline_position_of_flow_if_necessary(&mut self.block_flow,
|
||||||
|
solution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,14 +321,13 @@ impl Flow for TableWrapperFlow {
|
||||||
containing_block_inline_size;
|
containing_block_inline_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.compute_used_inline_size(layout_context, containing_block_inline_size);
|
self.compute_used_inline_size(layout_context,
|
||||||
|
containing_block_inline_size,
|
||||||
|
intermediate_column_inline_sizes.as_slice());
|
||||||
|
|
||||||
match self.table_layout {
|
if let TableLayout::Auto = self.table_layout {
|
||||||
TableLayout::Fixed => {}
|
self.calculate_table_column_sizes_for_automatic_layout(
|
||||||
TableLayout::Auto => {
|
&mut intermediate_column_inline_sizes)
|
||||||
self.calculate_table_column_sizes_for_automatic_layout(
|
|
||||||
&mut intermediate_column_inline_sizes)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let inline_start_content_edge = self.block_flow.fragment.border_box.start.i;
|
let inline_start_content_edge = self.block_flow.fragment.border_box.start.i;
|
||||||
|
@ -679,3 +705,86 @@ struct IntermediateColumnInlineSize {
|
||||||
percentage: f64,
|
percentage: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initial_computed_inline_size(block: &mut BlockFlow,
|
||||||
|
containing_block_inline_size: Au,
|
||||||
|
minimum_width_of_all_columns: Au)
|
||||||
|
-> MaybeAuto {
|
||||||
|
let inline_size_from_style = MaybeAuto::from_style(block.fragment.style.content_inline_size(),
|
||||||
|
containing_block_inline_size);
|
||||||
|
match inline_size_from_style {
|
||||||
|
MaybeAuto::Auto => {
|
||||||
|
MaybeAuto::Specified(Au::max(containing_block_inline_size,
|
||||||
|
minimum_width_of_all_columns))
|
||||||
|
}
|
||||||
|
MaybeAuto::Specified(inline_size_from_style) => {
|
||||||
|
MaybeAuto::Specified(Au::max(inline_size_from_style, minimum_width_of_all_columns))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Table {
|
||||||
|
minimum_width_of_all_columns: Au,
|
||||||
|
border_collapse: border_collapse::T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ISizeAndMarginsComputer for Table {
|
||||||
|
fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) {
|
||||||
|
block.fragment.compute_border_and_padding(containing_block_inline_size,
|
||||||
|
self.border_collapse)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initial_computed_inline_size(&self,
|
||||||
|
block: &mut BlockFlow,
|
||||||
|
parent_flow_inline_size: Au,
|
||||||
|
layout_context: &LayoutContext)
|
||||||
|
-> MaybeAuto {
|
||||||
|
let containing_block_inline_size =
|
||||||
|
self.containing_block_inline_size(block,
|
||||||
|
parent_flow_inline_size,
|
||||||
|
layout_context);
|
||||||
|
initial_computed_inline_size(block,
|
||||||
|
containing_block_inline_size,
|
||||||
|
self.minimum_width_of_all_columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve_inline_size_constraints(&self,
|
||||||
|
block: &mut BlockFlow,
|
||||||
|
input: &ISizeConstraintInput)
|
||||||
|
-> ISizeConstraintSolution {
|
||||||
|
self.solve_block_inline_size_constraints(block, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FloatedTable {
|
||||||
|
minimum_width_of_all_columns: Au,
|
||||||
|
border_collapse: border_collapse::T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ISizeAndMarginsComputer for FloatedTable {
|
||||||
|
fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) {
|
||||||
|
block.fragment.compute_border_and_padding(containing_block_inline_size,
|
||||||
|
self.border_collapse)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn initial_computed_inline_size(&self,
|
||||||
|
block: &mut BlockFlow,
|
||||||
|
parent_flow_inline_size: Au,
|
||||||
|
layout_context: &LayoutContext)
|
||||||
|
-> MaybeAuto {
|
||||||
|
let containing_block_inline_size =
|
||||||
|
self.containing_block_inline_size(block,
|
||||||
|
parent_flow_inline_size,
|
||||||
|
layout_context);
|
||||||
|
initial_computed_inline_size(block,
|
||||||
|
containing_block_inline_size,
|
||||||
|
self.minimum_width_of_all_columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve_inline_size_constraints(&self,
|
||||||
|
block: &mut BlockFlow,
|
||||||
|
input: &ISizeConstraintInput)
|
||||||
|
-> ISizeConstraintSolution {
|
||||||
|
FloatNonReplaced.solve_inline_size_constraints(block, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,6 +296,7 @@ experimental == rtl_simple.html rtl_simple_ref.html
|
||||||
== table_expansion_to_fit_a.html table_expansion_to_fit_ref.html
|
== table_expansion_to_fit_a.html table_expansion_to_fit_ref.html
|
||||||
== table_float_translation_a.html table_float_translation_ref.html
|
== table_float_translation_a.html table_float_translation_ref.html
|
||||||
== table_intrinsic_style_specified_width_a.html table_intrinsic_style_specified_width_ref.html
|
== table_intrinsic_style_specified_width_a.html table_intrinsic_style_specified_width_ref.html
|
||||||
|
== table_margin_auto_a.html table_margin_auto_ref.html
|
||||||
== table_padding_a.html table_padding_ref.html
|
== table_padding_a.html table_padding_ref.html
|
||||||
== table_percentage_capping_a.html table_percentage_capping_ref.html
|
== table_percentage_capping_a.html table_percentage_capping_ref.html
|
||||||
== table_percentage_width_a.html table_percentage_width_ref.html
|
== table_percentage_width_a.html table_percentage_width_ref.html
|
||||||
|
|
20
tests/ref/table_margin_auto_a.html
Normal file
20
tests/ref/table_margin_auto_a.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body, html {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
margin: auto;
|
||||||
|
width: 0px;
|
||||||
|
border-spacing: 0;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table><tr><td>Foooooooooooooooooooooooooooooo</td></tr></table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
21
tests/ref/table_margin_auto_ref.html
Normal file
21
tests/ref/table_margin_auto_ref.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body, html {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>Foooooooooooooooooooooooooooooo</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue