mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
layout: Implement empty-cells
per CSS 2.1 § 17.6.1.1.
This commit is contained in:
parent
592c93e0c2
commit
5675274c44
8 changed files with 98 additions and 13 deletions
|
@ -52,7 +52,7 @@ use std::collections::DList;
|
|||
use std::mem;
|
||||
use std::sync::atomic::Relaxed;
|
||||
use style::ComputedValues;
|
||||
use style::computed_values::{display, position, float, list_style_position};
|
||||
use style::computed_values::{display, empty_cells, float, list_style_position, position};
|
||||
use sync::Arc;
|
||||
use url::Url;
|
||||
|
||||
|
@ -157,8 +157,8 @@ struct InlineFragmentsAccumulator {
|
|||
/// The list of fragments.
|
||||
fragments: DList<Fragment>,
|
||||
|
||||
/// Whether we've created a range to enclose all the fragments. This will be Some() if the outer node
|
||||
/// is an inline and None otherwise.
|
||||
/// Whether we've created a range to enclose all the fragments. This will be Some() if the
|
||||
/// outer node is an inline and None otherwise.
|
||||
enclosing_style: Option<Arc<ComputedValues>>,
|
||||
}
|
||||
|
||||
|
@ -914,7 +914,18 @@ impl<'a> FlowConstructor<'a> {
|
|||
/// possibly other `BlockFlow`s or `InlineFlow`s underneath it.
|
||||
fn build_flow_for_table_cell(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
|
||||
let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableCell);
|
||||
let flow = box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow>;
|
||||
|
||||
// Determine if the table cell should be hidden. Per CSS 2.1 § 17.6.1.1, this will be true
|
||||
// if the cell has any in-flow elements (even empty ones!) and has `empty-cells` set to
|
||||
// `hide`.
|
||||
let hide = node.style().get_inheritedtable().empty_cells == empty_cells::hide &&
|
||||
node.children().all(|kid| {
|
||||
let position = kid.style().get_box().position;
|
||||
!kid.is_content() || position == position::absolute || position == position::fixed
|
||||
});
|
||||
|
||||
let flow = box TableCellFlow::from_node_fragment_and_visibility_flag(node, fragment, !hide)
|
||||
as Box<Flow>;
|
||||
self.build_flow_for_block(FlowRef::new(flow), node)
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ use std::iter::Zip;
|
|||
use std::raw;
|
||||
use std::sync::atomic::{AtomicUint, SeqCst};
|
||||
use std::slice::MutItems;
|
||||
use style::computed_values::{clear, float, position, text_align};
|
||||
use style::computed_values::{clear, empty_cells, float, position, text_align};
|
||||
use style::ComputedValues;
|
||||
use sync::Arc;
|
||||
|
||||
|
@ -1067,12 +1067,18 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
|
|||
fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> FlowRef {
|
||||
let flow = match self.class() {
|
||||
FlowClass::Table | FlowClass::TableRowGroup => {
|
||||
let fragment = Fragment::new_anonymous_table_fragment(node, SpecificFragmentInfo::TableRow);
|
||||
let fragment =
|
||||
Fragment::new_anonymous_table_fragment(node,
|
||||
SpecificFragmentInfo::TableRow);
|
||||
box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow>
|
||||
},
|
||||
FlowClass::TableRow => {
|
||||
let fragment = Fragment::new_anonymous_table_fragment(node, SpecificFragmentInfo::TableCell);
|
||||
box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow>
|
||||
let fragment =
|
||||
Fragment::new_anonymous_table_fragment(node,
|
||||
SpecificFragmentInfo::TableCell);
|
||||
let hide = node.style().get_inheritedtable().empty_cells == empty_cells::hide;
|
||||
box TableCellFlow::from_node_fragment_and_visibility_flag(node, fragment, !hide) as
|
||||
Box<Flow>
|
||||
},
|
||||
_ => {
|
||||
panic!("no need to generate a missing child")
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
|
||||
use context::LayoutContext;
|
||||
use flow::{FlowClass, Flow};
|
||||
use flow::{Flow, FlowClass};
|
||||
use fragment::{Fragment, FragmentBoundsIterator};
|
||||
use model::{MaybeAuto};
|
||||
use layout_debug;
|
||||
|
@ -27,15 +27,21 @@ pub struct TableCellFlow {
|
|||
pub block_flow: BlockFlow,
|
||||
/// The column span of this cell.
|
||||
pub column_span: u32,
|
||||
/// Whether this cell is visible. If false, the value of `empty-cells` means that we must not
|
||||
/// display this cell.
|
||||
pub visible: bool,
|
||||
}
|
||||
|
||||
impl TableCellFlow {
|
||||
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment)
|
||||
-> TableCellFlow {
|
||||
pub fn from_node_fragment_and_visibility_flag(node: &ThreadSafeLayoutNode,
|
||||
fragment: Fragment,
|
||||
visible: bool)
|
||||
-> TableCellFlow {
|
||||
TableCellFlow {
|
||||
block_flow: BlockFlow::from_node_and_fragment(node, fragment),
|
||||
column_span: node.get_unsigned_integer_attribute(UnsignedIntegerAttribute::ColSpanUnsignedIntegerAttribute)
|
||||
.unwrap_or(1),
|
||||
visible: visible,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +59,9 @@ impl TableCellFlow {
|
|||
/// methods.
|
||||
#[inline(always)]
|
||||
fn assign_block_size_table_cell_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
|
||||
self.block_flow.assign_block_size_block_base(layout_context, MarginsMayCollapseFlag::MarginsMayNotCollapse)
|
||||
self.block_flow.assign_block_size_block_base(
|
||||
layout_context,
|
||||
MarginsMayCollapseFlag::MarginsMayNotCollapse)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,7 +153,9 @@ impl Flow for TableCellFlow {
|
|||
}
|
||||
|
||||
fn build_display_list(&mut self, layout_context: &LayoutContext) {
|
||||
self.block_flow.build_display_list(layout_context)
|
||||
if self.visible {
|
||||
self.block_flow.build_display_list(layout_context)
|
||||
}
|
||||
}
|
||||
|
||||
fn repair_style(&mut self, new_style: &Arc<ComputedValues>) {
|
||||
|
|
|
@ -1000,6 +1000,15 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
|||
_ => panic!("no layout data for this node"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this node contributes content. This is used in the implementation of
|
||||
/// `empty_cells` per CSS 2.1 § 17.6.1.1.
|
||||
pub fn is_content(&self) -> bool {
|
||||
match self.type_id() {
|
||||
Some(NodeTypeId::Element(..)) | Some(NodeTypeId::Text(..)) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ThreadSafeLayoutNodeChildrenIterator<'a> {
|
||||
|
|
|
@ -1326,6 +1326,10 @@ pub mod longhands {
|
|||
|
||||
${single_keyword("table-layout", "auto fixed")}
|
||||
|
||||
${new_style_struct("InheritedTable", is_inherited=True)}
|
||||
|
||||
${single_keyword("empty-cells", "show hide")}
|
||||
|
||||
// CSS 2.1, Section 18 - User interface
|
||||
|
||||
|
||||
|
|
|
@ -215,3 +215,4 @@ fragment=top != ../html/acid2.html acid2_ref.html
|
|||
== legacy_table_border_attribute_a.html legacy_table_border_attribute_ref.html
|
||||
== inset.html inset_ref.html
|
||||
== outset.html outset_ref.html
|
||||
== empty_cells_a.html empty_cells_ref.html
|
||||
|
|
25
tests/ref/empty_cells_a.html
Normal file
25
tests/ref/empty_cells_a.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Tests that `empty-cells` works—in particular, that the definition of emptiness is correct. -->
|
||||
<style>
|
||||
table {
|
||||
empty-cells: hide;
|
||||
}
|
||||
section {
|
||||
float: right;
|
||||
}
|
||||
nav {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table border=3>
|
||||
<tr><td>Yo</td><td>Howdy</td><td><section> </section></td><td></td></tr>
|
||||
<tr><td>Later</td><td><nav></nav></td><td>See ya</td><td>Aloha</td></tr>
|
||||
<tr><td></td><td>Sayonara</td><td></td><td><span></span></td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
19
tests/ref/empty_cells_ref.html
Normal file
19
tests/ref/empty_cells_ref.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Tests that `empty-cells` works—in particular, that the definition of emptiness is correct. -->
|
||||
<style>
|
||||
.empty {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table border=3>
|
||||
<tr><td>Yo</td><td>Howdy</td><td></td><td class=empty></td></tr>
|
||||
<tr><td>Later</td><td class=empty></td><td>See ya</td><td>Aloha</td></tr>
|
||||
<tr><td class=empty></td><td>Sayonara</td><td class=empty></td><td></td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue