aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-09-19 19:50:47 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-09-19 19:50:47 -0700
commitccda8f204acb014387e92f1ecd47355e9e45ed89 (patch)
tree2c7aedad686c431c25d7d142d7aacc191b51a014
parente9ad87e27eb30cfacd66b575e104ee2784f95591 (diff)
parent5bdc21e2240c49f2b1145f8a9e06551c5a0ddba4 (diff)
downloadservo-ccda8f204acb014387e92f1ecd47355e9e45ed89.tar.gz
servo-ccda8f204acb014387e92f1ecd47355e9e45ed89.zip
Merge pull request #3420 from glennw/table-debug
Adds support for table layout trace and updates viewer for tables.
-rw-r--r--components/layout/block.rs2
-rw-r--r--components/layout/flow.rs36
-rw-r--r--components/layout/table.rs11
-rw-r--r--components/layout/table_cell.rs11
-rw-r--r--components/layout/table_colgroup.rs4
-rw-r--r--components/layout/table_row.rs11
-rw-r--r--components/layout/table_rowgroup.rs11
-rw-r--r--components/layout/table_wrapper.rs12
-rw-r--r--etc/layout_viewer/viewer.html30
9 files changed, 118 insertions, 10 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index c527412156f..ad5eb03cc3f 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -1481,7 +1481,7 @@ impl Flow for BlockFlow {
///
/// TODO(pcwalton): Inline blocks.
fn bubble_inline_sizes(&mut self, _: &LayoutContext) {
- let _scope = layout_debug_scope!("bubble_inline_sizes {:s}", self.base.debug_id());
+ let _scope = layout_debug_scope!("block::bubble_inline_sizes {:s}", self.base.debug_id());
let mut flags = self.base.flags;
flags.set_has_left_floated_descendants(false);
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index e5e869dcc15..467a24f9a7a 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -103,11 +103,22 @@ pub trait Flow: fmt::Show + ToString + Share {
fail!("called as_table_wrapper() on a non-tablewrapper flow")
}
+ /// If this is a table wrapper flow, returns the underlying object, borrowed immutably. Fails
+ /// otherwise.
+ fn as_immutable_table_wrapper<'a>(&'a self) -> &'a TableWrapperFlow {
+ fail!("called as_immutable_table_wrapper() on a non-tablewrapper flow")
+ }
+
/// If this is a table flow, returns the underlying object. Fails otherwise.
fn as_table<'a>(&'a mut self) -> &'a mut TableFlow {
fail!("called as_table() on a non-table flow")
}
+ /// If this is a table flow, returns the underlying object, borrowed immutably. Fails otherwise.
+ fn as_immutable_table<'a>(&'a self) -> &'a TableFlow {
+ fail!("called as_table() on a non-table flow")
+ }
+
/// If this is a table colgroup flow, returns the underlying object. Fails otherwise.
fn as_table_colgroup<'a>(&'a mut self) -> &'a mut TableColGroupFlow {
fail!("called as_table_colgroup() on a non-tablecolgroup flow")
@@ -118,11 +129,23 @@ pub trait Flow: fmt::Show + ToString + Share {
fail!("called as_table_rowgroup() on a non-tablerowgroup flow")
}
+ /// If this is a table rowgroup flow, returns the underlying object, borrowed immutably. Fails
+ /// otherwise.
+ fn as_immutable_table_rowgroup<'a>(&'a self) -> &'a TableRowGroupFlow {
+ fail!("called as_table_rowgroup() on a non-tablerowgroup flow")
+ }
+
/// If this is a table row flow, returns the underlying object. Fails otherwise.
fn as_table_row<'a>(&'a mut self) -> &'a mut TableRowFlow {
fail!("called as_table_row() on a non-tablerow flow")
}
+ /// If this is a table row flow, returns the underlying object, borrowed immutably. Fails
+ /// otherwise.
+ fn as_immutable_table_row<'a>(&'a self) -> &'a TableRowFlow {
+ fail!("called as_table_row() on a non-tablerow flow")
+ }
+
/// If this is a table cell flow, returns the underlying object. Fails otherwise.
fn as_table_caption<'a>(&'a mut self) -> &'a mut TableCaptionFlow {
fail!("called as_table_caption() on a non-tablecaption flow")
@@ -133,6 +156,12 @@ pub trait Flow: fmt::Show + ToString + Share {
fail!("called as_table_cell() on a non-tablecell flow")
}
+ /// If this is a table cell flow, returns the underlying object, borrowed immutably. Fails
+ /// otherwise.
+ fn as_immutable_table_cell<'a>(&'a self) -> &'a TableCellFlow {
+ fail!("called as_table_cell() on a non-tablecell flow")
+ }
+
/// If this is a table row or table rowgroup or table flow, returns column inline-sizes.
/// Fails otherwise.
fn col_inline_sizes<'a>(&'a mut self) -> &'a mut Vec<Au> {
@@ -289,7 +318,12 @@ impl<'a, E, S: Encoder<E>> Encodable<S, E> for &'a Flow {
match self.class() {
BlockFlowClass => self.as_immutable_block().encode(e),
InlineFlowClass => self.as_immutable_inline().encode(e),
- _ => { Ok(()) } // TODO: Support tables
+ TableFlowClass => self.as_immutable_table().encode(e),
+ TableWrapperFlowClass => self.as_immutable_table_wrapper().encode(e),
+ TableRowGroupFlowClass => self.as_immutable_table_rowgroup().encode(e),
+ TableRowFlowClass => self.as_immutable_table_row().encode(e),
+ TableCellFlowClass => self.as_immutable_table_cell().encode(e),
+ _ => { Ok(()) } // TODO: Support captions
}
})
})
diff --git a/components/layout/table.rs b/components/layout/table.rs
index 6803718a56d..744e031fdfa 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -13,6 +13,7 @@ use context::LayoutContext;
use floats::FloatKind;
use flow::{TableFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use fragment::Fragment;
+use layout_debug;
use table_wrapper::{TableLayout, FixedLayout, AutoLayout};
use wrapper::ThreadSafeLayoutNode;
@@ -25,6 +26,7 @@ use style::computed_values::table_layout;
/// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
/// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment,
/// not table fragment per CSS 2.1 § 10.5.
+#[deriving(Encodable)]
pub struct TableFlow {
pub block_flow: BlockFlow,
@@ -145,6 +147,10 @@ impl Flow for TableFlow {
self
}
+ fn as_immutable_table<'a>(&'a self) -> &'a TableFlow {
+ self
+ }
+
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
&mut self.block_flow
}
@@ -166,6 +172,9 @@ impl Flow for TableFlow {
/// The maximum min/pref inline-sizes of each column are set from the rows for the automatic
/// table layout calculation.
fn bubble_inline_sizes(&mut self, _: &LayoutContext) {
+ let _scope = layout_debug_scope!("table::bubble_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
+
let mut min_inline_size = Au(0);
let mut pref_inline_size = Au(0);
let mut did_first_row = false;
@@ -241,6 +250,8 @@ impl Flow for TableFlow {
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When
/// called on this context, the context has had its inline-size set by the parent context.
fn assign_inline_sizes(&mut self, ctx: &LayoutContext) {
+ let _scope = layout_debug_scope!("table::assign_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table");
// The position was set to the containing block by the flow's parent.
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 0011cd29fbc..69ae3d83d81 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -11,6 +11,7 @@ use context::LayoutContext;
use flow::{TableCellFlowClass, FlowClass, Flow};
use fragment::Fragment;
use model::{MaybeAuto};
+use layout_debug;
use table::InternalTable;
use wrapper::ThreadSafeLayoutNode;
@@ -18,6 +19,7 @@ use servo_util::geometry::Au;
use std::fmt;
/// A table formatting context.
+#[deriving(Encodable)]
pub struct TableCellFlow {
/// Data common to all flows.
pub block_flow: BlockFlow,
@@ -64,12 +66,19 @@ impl Flow for TableCellFlow {
self
}
+ fn as_immutable_table_cell<'a>(&'a self) -> &'a TableCellFlow {
+ self
+ }
+
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
&mut self.block_flow
}
/// Minimum/preferred inline-sizes set by this function are used in automatic table layout calculation.
fn bubble_inline_sizes(&mut self, ctx: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_cell::bubble_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
+
self.block_flow.bubble_inline_sizes(ctx);
let specified_inline_size = MaybeAuto::from_style(self.block_flow.fragment.style().content_inline_size(),
Au::new(0)).specified_or_zero();
@@ -86,6 +95,8 @@ impl Flow for TableCellFlow {
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When
/// called on this context, the context has had its inline-size set by the parent table row.
fn assign_inline_sizes(&mut self, ctx: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_cell::assign_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_cell");
// The position was set to the column inline-size by the parent flow, table row flow.
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index 270f55970b2..ab206c5da18 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -9,6 +9,7 @@
use context::LayoutContext;
use flow::{BaseFlow, TableColGroupFlowClass, FlowClass, Flow};
use fragment::{Fragment, TableColumnFragment};
+use layout_debug;
use model::{MaybeAuto};
use wrapper::ThreadSafeLayoutNode;
@@ -53,6 +54,9 @@ impl Flow for TableColGroupFlow {
}
fn bubble_inline_sizes(&mut self, _: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_colgroup::bubble_inline_sizes {:s}",
+ self.base.debug_id());
+
for fragment in self.cols.iter() {
// get the specified value from inline-size property
let inline_size = MaybeAuto::from_style(fragment.style().content_inline_size(),
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 1015cb9f593..6420d4db62d 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -13,6 +13,7 @@ use context::LayoutContext;
use flow::{TableRowFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use flow;
use fragment::Fragment;
+use layout_debug;
use table::InternalTable;
use model::{MaybeAuto, Specified, Auto};
use wrapper::ThreadSafeLayoutNode;
@@ -22,6 +23,7 @@ use std::cmp::max;
use std::fmt;
/// A table formatting context.
+#[deriving(Encodable)]
pub struct TableRowFlow {
pub block_flow: BlockFlow,
@@ -143,6 +145,10 @@ impl Flow for TableRowFlow {
self
}
+ fn as_immutable_table_row<'a>(&'a self) -> &'a TableRowFlow {
+ self
+ }
+
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
&mut self.block_flow
}
@@ -166,6 +172,9 @@ impl Flow for TableRowFlow {
/// Min/pref inline-sizes set by this function are used in automatic table layout calculation.
/// The specified column inline-sizes of children cells are used in fixed table layout calculation.
fn bubble_inline_sizes(&mut self, _: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_row::bubble_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
+
let mut min_inline_size = Au(0);
let mut pref_inline_size = Au(0);
/* find the specified inline_sizes from child table-cell contexts */
@@ -195,6 +204,8 @@ impl Flow for TableRowFlow {
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When called
/// on this context, the context has had its inline-size set by the parent context.
fn assign_inline_sizes(&mut self, ctx: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_row::assign_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_row");
// The position was set to the containing block by the flow's parent.
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index 221df0e4375..78233de9c72 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -13,6 +13,7 @@ use context::LayoutContext;
use flow::{TableRowGroupFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use flow;
use fragment::Fragment;
+use layout_debug;
use table::{InternalTable, TableFlow};
use wrapper::ThreadSafeLayoutNode;
@@ -21,6 +22,7 @@ use std::cmp::max;
use std::fmt;
/// A table formatting context.
+#[deriving(Encodable)]
pub struct TableRowGroupFlow {
pub block_flow: BlockFlow,
@@ -110,6 +112,10 @@ impl Flow for TableRowGroupFlow {
self
}
+ fn as_immutable_table_rowgroup<'a>(&'a self) -> &'a TableRowGroupFlow {
+ self
+ }
+
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
&mut self.block_flow
}
@@ -134,6 +140,9 @@ impl Flow for TableRowGroupFlow {
/// Also, this function finds the specified column inline-sizes from the first row.
/// Those are used in fixed table layout calculation
fn bubble_inline_sizes(&mut self, _: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_rowgroup::bubble_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
+
let mut min_inline_size = Au(0);
let mut pref_inline_size = Au(0);
@@ -176,6 +185,8 @@ impl Flow for TableRowGroupFlow {
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When
/// called on this context, the context has had its inline-size set by the parent context.
fn assign_inline_sizes(&mut self, ctx: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_rowgroup::assign_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_rowgroup");
// The position was set to the containing block by the flow's parent.
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index df2b2129b7a..486778a6509 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -13,6 +13,7 @@ use context::LayoutContext;
use floats::FloatKind;
use flow::{TableWrapperFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use fragment::Fragment;
+use layout_debug;
use model::{Specified, Auto, specified};
use wrapper::ThreadSafeLayoutNode;
@@ -21,12 +22,14 @@ use std::cmp::max;
use std::fmt;
use style::computed_values::table_layout;
+#[deriving(Encodable)]
pub enum TableLayout {
FixedLayout,
AutoLayout
}
/// A table wrapper flow based on a block formatting context.
+#[deriving(Encodable)]
pub struct TableWrapperFlow {
pub block_flow: BlockFlow,
@@ -119,6 +122,10 @@ impl Flow for TableWrapperFlow {
self
}
+ fn as_immutable_table_wrapper<'a>(&'a self) -> &'a TableWrapperFlow {
+ self
+ }
+
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
&mut self.block_flow
}
@@ -130,6 +137,9 @@ impl Flow for TableWrapperFlow {
any fragments it is responsible for flowing. */
fn bubble_inline_sizes(&mut self, ctx: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_wrapper::bubble_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
+
// get column inline-sizes info from table flow
for kid in self.block_flow.base.child_iter() {
assert!(kid.is_table_caption() || kid.is_table());
@@ -148,6 +158,8 @@ impl Flow for TableWrapperFlow {
/// Dual fragments consume some inline-size first, and the remainder is assigned to all child (block)
/// contexts.
fn assign_inline_sizes(&mut self, ctx: &LayoutContext) {
+ let _scope = layout_debug_scope!("table_wrapper::assign_inline_sizes {:s}",
+ self.block_flow.base.debug_id());
debug!("assign_inline_sizes({}): assigning inline_size for flow",
if self.is_float() {
"floated table_wrapper"
diff --git a/etc/layout_viewer/viewer.html b/etc/layout_viewer/viewer.html
index c278ca85a36..c173ec2c365 100644
--- a/etc/layout_viewer/viewer.html
+++ b/etc/layout_viewer/viewer.html
@@ -89,16 +89,26 @@
<script src="js/formatters.min.js"></script>
<script>
+ function get_base(node) {
+ if (node.data.base !== undefined) {
+ return node.data.base;
+ }
+ if (node.data.block_flow.base !== undefined) {
+ return node.data.block_flow.base;
+ }
+ throw "Unknown node type";
+ }
+
function create_flow_tree(trace_node) {
var node = {
- text: trace_node.class + " (" + trace_node.data.base.id + ")",
- id: trace_node.data.base.id,
+ text: trace_node.class + " (" + get_base(trace_node).id + ")",
+ id: get_base(trace_node).id,
icon: "dummy",
};
var children = [];
- for (var i=0 ; i < trace_node.data.base.children.length ; ++i) {
- children.push(create_flow_tree(trace_node.data.base.children[i]));
+ for (var i=0 ; i < get_base(trace_node).children.length ; ++i) {
+ children.push(create_flow_tree(get_base(trace_node).children[i]));
}
if (children.length > 0) {
@@ -109,13 +119,13 @@
}
function create_flow_hash(trace_node, flow_hash) {
- flow_hash[trace_node.data.base.id] = trace_node;
+ flow_hash[get_base(trace_node).id] = trace_node;
- for (var i=0 ; i < trace_node.data.base.children.length ; ++i) {
- create_flow_hash(trace_node.data.base.children[i], flow_hash);
+ for (var i=0 ; i < get_base(trace_node).children.length ; ++i) {
+ create_flow_hash(get_base(trace_node).children[i], flow_hash);
}
- delete trace_node.data.base.children;
+ delete get_base(trace_node).children;
}
function flatten_trace(trace_node) {
@@ -182,6 +192,10 @@
if (obj.data !== undefined && obj.data.base !== undefined) {
return obj.data.base.id;
}
+ if (obj.data !== undefined && obj.data.block_flow !== undefined &&
+ obj.data.block_flow.base !== undefined) {
+ return obj.data.block_flow.base.id;
+ }
if (obj.id !== undefined) {
return obj.id;
}