aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-12-16 22:29:10 -0800
committerPatrick Walton <pcwalton@mimiga.net>2014-12-17 22:06:14 -0800
commita3f6f4e75bcfca151a85f67c19f206cce7f38d30 (patch)
tree76b750f21d451141fca4b3978932180792ee447b
parent636641f90533c941a3580b5caee1ae1fef953841 (diff)
downloadservo-a3f6f4e75bcfca151a85f67c19f206cce7f38d30.tar.gz
servo-a3f6f4e75bcfca151a85f67c19f206cce7f38d30.zip
layout: Implement `caption-side` per CSS 2.1 § 17.4.1.
`caption-side` is used by 4% of pages by number of loads.
-rw-r--r--components/layout/construct.rs45
-rw-r--r--components/style/properties/mod.rs.mako2
-rw-r--r--tests/ref/basic.list2
-rw-r--r--tests/ref/table_caption_bottom_a.html28
-rw-r--r--tests/ref/table_caption_bottom_ref.html27
-rw-r--r--tests/ref/table_caption_top_a.html28
-rw-r--r--tests/ref/table_caption_top_ref.html27
7 files changed, 144 insertions, 15 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 4422c8bfcdf..a5fef43df0b 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -52,7 +52,8 @@ use std::collections::DList;
use std::mem;
use std::sync::atomic::Relaxed;
use style::ComputedValues;
-use style::computed_values::{display, empty_cells, float, list_style_position, position};
+use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
+use style::computed_values::{position};
use sync::Arc;
use url::Url;
@@ -778,19 +779,26 @@ impl<'a> FlowConstructor<'a> {
}
}
- /// TableCaptionFlow is populated underneath TableWrapperFlow
- fn place_table_caption_under_table_wrapper(&mut self,
- table_wrapper_flow: &mut FlowRef,
- node: &ThreadSafeLayoutNode) {
+ /// Places any table captions found under the given table wrapper, if the value of their
+ /// `caption-side` property is equal to the given `side`.
+ fn place_table_caption_under_table_wrapper_on_side(&mut self,
+ table_wrapper_flow: &mut FlowRef,
+ node: &ThreadSafeLayoutNode,
+ side: caption_side::T) {
+ // Only flows that are table captions are matched here.
for kid in node.children() {
match kid.swap_out_construction_result() {
- ConstructionResult::None | ConstructionResult::ConstructionItem(_) => {}
- ConstructionResult::Flow(kid_flow, _) => {
- // Only kid flows with table-caption are matched here.
- if kid_flow.deref().is_table_caption() {
+ ConstructionResult::Flow(mut kid_flow, _) => {
+ if kid_flow.deref().is_table_caption() &&
+ kid_flow.as_block()
+ .fragment
+ .style()
+ .get_inheritedtable()
+ .caption_side == side {
table_wrapper_flow.add_new_child(kid_flow);
}
}
+ ConstructionResult::None | ConstructionResult::ConstructionItem(_) => {}
}
}
}
@@ -842,17 +850,19 @@ impl<'a> FlowConstructor<'a> {
let table_flow = box TableFlow::from_node_and_fragment(node, table_fragment);
let table_flow = FlowRef::new(table_flow as Box<Flow>);
- // We first populate the TableFlow with other flows than TableCaptionFlow.
- // We then populate the TableWrapperFlow with TableCaptionFlow, and attach
- // the TableFlow to the TableWrapperFlow
+ // First populate the table flow with its children.
let construction_result = self.build_flow_for_block(table_flow, node);
- self.place_table_caption_under_table_wrapper(&mut wrapper_flow, node);
let mut abs_descendants = Descendants::new();
let mut fixed_descendants = Descendants::new();
- // NOTE: The order of captions and table are not the same order as in the DOM tree.
- // All caption blocks are placed before the table flow
+ // The order of the caption and the table are not necessarily the same order as in the DOM
+ // tree. All caption blocks are placed before or after the table flow, depending on the
+ // value of `caption-side`.
+ self.place_table_caption_under_table_wrapper_on_side(&mut wrapper_flow,
+ node,
+ caption_side::top);
+
match construction_result {
ConstructionResult::Flow(table_flow, table_abs_descendants) => {
wrapper_flow.add_new_child(table_flow);
@@ -861,6 +871,11 @@ impl<'a> FlowConstructor<'a> {
_ => {}
}
+ // If the value of `caption-side` is `bottom`, place it now.
+ self.place_table_caption_under_table_wrapper_on_side(&mut wrapper_flow,
+ node,
+ caption_side::bottom);
+
// The flow is done.
wrapper_flow.finish();
let is_positioned = wrapper_flow.as_block().is_positioned();
diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako
index 0456bc66cc4..3541677e0d9 100644
--- a/components/style/properties/mod.rs.mako
+++ b/components/style/properties/mod.rs.mako
@@ -1330,6 +1330,8 @@ pub mod longhands {
${single_keyword("empty-cells", "show hide")}
+ ${single_keyword("caption-side", "top bottom")}
+
// CSS 2.1, Section 18 - User interface
diff --git a/tests/ref/basic.list b/tests/ref/basic.list
index db32e010f43..b316ddaa3fe 100644
--- a/tests/ref/basic.list
+++ b/tests/ref/basic.list
@@ -216,3 +216,5 @@ fragment=top != ../html/acid2.html acid2_ref.html
== inset.html inset_ref.html
== outset.html outset_ref.html
== empty_cells_a.html empty_cells_ref.html
+== table_caption_top_a.html table_caption_top_ref.html
+== table_caption_bottom_a.html table_caption_bottom_ref.html
diff --git a/tests/ref/table_caption_bottom_a.html b/tests/ref/table_caption_bottom_a.html
new file mode 100644
index 00000000000..239abb84b3c
--- /dev/null
+++ b/tests/ref/table_caption_bottom_a.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!-- Tests that `caption-side` places the caption on the right side. -->
+<style>
+caption {
+ background-color: blue;
+ color: white;
+ caption-side: bottom;
+ padding: 0;
+ text-align: left;
+ width: 500px;
+}
+table {
+ width: 500px;
+}
+</style>
+</head>
+<body>
+<table border=0 cellspacing=0 cellpadding=0>
+ <tr><td>Kitten</td><td>Kätzchen</td><td>Chaton</td><td>Koneko</td></tr>
+ <tr><td>Cat</td><td>Katze</td><td>Chat</td><td>Neko</td></tr>
+ <caption>Vocabulary</caption>
+ <tr><td>Dog</td><td>Hund</td><td>Chien</td><td>Inu</td></tr>
+</table>
+</body>
+</html>
+
diff --git a/tests/ref/table_caption_bottom_ref.html b/tests/ref/table_caption_bottom_ref.html
new file mode 100644
index 00000000000..7c5dde58bd0
--- /dev/null
+++ b/tests/ref/table_caption_bottom_ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!-- Tests that `caption-side` places the caption on the right side. -->
+<style>
+section {
+ background-color: blue;
+ color: white;
+ padding: 0;
+ text-align: left;
+ width: 500px;
+}
+table {
+ width: 500px;
+}
+</style>
+</head>
+<body>
+<table border=0 cellspacing=0 cellpadding=0>
+ <tr><td>Kitten</td><td>Kätzchen</td><td>Chaton</td><td>Koneko</td></tr>
+ <tr><td>Cat</td><td>Katze</td><td>Chat</td><td>Neko</td></tr>
+ <tr><td>Dog</td><td>Hund</td><td>Chien</td><td>Inu</td></tr>
+</table>
+<section>Vocabulary</section>
+</body>
+</html>
+
diff --git a/tests/ref/table_caption_top_a.html b/tests/ref/table_caption_top_a.html
new file mode 100644
index 00000000000..16b87dcec9b
--- /dev/null
+++ b/tests/ref/table_caption_top_a.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!-- Tests that `caption-side` places the caption on the right side. -->
+<style>
+caption {
+ background-color: blue;
+ color: white;
+ caption-side: top;
+ padding: 0;
+ text-align: left;
+ width: 500px;
+}
+table {
+ width: 500px;
+}
+</style>
+</head>
+<body>
+<table border=0 cellspacing=0 cellpadding=0>
+ <tr><td>Kitten</td><td>Kätzchen</td><td>Chaton</td><td>Koneko</td></tr>
+ <caption>Vocabulary</caption>
+ <tr><td>Cat</td><td>Katze</td><td>Chat</td><td>Neko</td></tr>
+ <tr><td>Dog</td><td>Hund</td><td>Chien</td><td>Inu</td></tr>
+</table>
+</body>
+</html>
+
diff --git a/tests/ref/table_caption_top_ref.html b/tests/ref/table_caption_top_ref.html
new file mode 100644
index 00000000000..d22c3b5e050
--- /dev/null
+++ b/tests/ref/table_caption_top_ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!-- Tests that `caption-side` places the caption on the right side. -->
+<style>
+section {
+ background-color: blue;
+ color: white;
+ padding: 0;
+ text-align: left;
+ width: 500px;
+}
+table {
+ width: 500px;
+}
+</style>
+</head>
+<body>
+<section>Vocabulary</section>
+<table border=0 cellspacing=0 cellpadding=0>
+ <tr><td>Kitten</td><td>Kätzchen</td><td>Chaton</td><td>Koneko</td></tr>
+ <tr><td>Cat</td><td>Katze</td><td>Chat</td><td>Neko</td></tr>
+ <tr><td>Dog</td><td>Hund</td><td>Chien</td><td>Inu</td></tr>
+</table>
+</body>
+</html>
+