layout: Make box building thread safe by pushing down styles into

non-element children during the cascade.

Fetching them from the parent isn't thread-safe.

Adds a test for anonymous block box inheritance.
This commit is contained in:
Patrick Walton 2014-01-29 15:24:42 -08:00
parent 6c2e48f04d
commit 0e20ec02c5
6 changed files with 37 additions and 39 deletions

View file

@ -139,9 +139,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
}
for kid in self.children() {
if kid.is_element() {
kid.cascade_subtree(Some(*self));
}
kid.cascade_subtree(Some(*self));
}
}
}

View file

@ -298,36 +298,9 @@ pub struct InlineParentInfo {
impl Box {
/// Constructs a new `Box` instance.
pub fn new(node: LayoutNode, specific: SpecificBoxInfo) -> Box {
// Find the nearest ancestor element and take its style. (It should be either that node or
// its immediate parent.)
// CSS 2.1 § 9.2.1.1,9.2.2.1 This is for non-inherited properties on anonymous boxes
// example:
//
// <div style="border: solid">
// <p>Foo</p>
// Bar
// <p>Baz</p>
// </div>
//
// An anonymous block box is generated around `Bar`, but it shouldn't inherit the border.
let node_style = if node.is_element() {
node.style().clone()
} else {
let mut nearest_ancestor_element = node;
while !nearest_ancestor_element.is_element() {
nearest_ancestor_element =
nearest_ancestor_element.parent_node().expect("no nearest element?!");
}
// Anonymous box: inheriting from the ancestor with no specified declarations.
Arc::new(cascade(&[Arc::new(~[])],
Some(nearest_ancestor_element.style().get())))
};
Box {
node: OpaqueNode::from_layout_node(&node),
style: node_style,
style: node.style().clone(),
position: RefCell::new(Au::zero_rect()),
border: RefCell::new(Zero::zero()),
padding: RefCell::new(Zero::zero()),

View file

@ -134,16 +134,16 @@ fn match_and_cascade_node(unsafe_layout_node: UnsafeLayoutNode,
// Perform the CSS selector matching.
let stylist: &Stylist = cast::transmute(layout_context.stylist);
node.match_node(stylist);
// Perform the CSS cascade.
let parent_opt = if OpaqueNode::from_layout_node(&node) == layout_context.reflow_root {
None
} else {
node.parent_node()
};
node.cascade_node(parent_opt);
}
// Perform the CSS cascade.
let parent_opt = if OpaqueNode::from_layout_node(&node) == layout_context.reflow_root {
None
} else {
node.parent_node()
};
node.cascade_node(parent_opt);
// Enqueue kids.
let mut child_count = 0;
for kid in node.children() {

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title>hi</title>
</head>
<body>
<div style="border: solid">
<p>Foo</p>
Bar
<p>Baz</p>
</div>
</body>
</html>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title>hi</title>
</head>
<body>
<div style="border: solid">
<p>Foo</p>
<div>Bar</div>
<p>Baz</p>
</div>
</body>
</html>

View file

@ -25,3 +25,4 @@
== img_size_a.html img_size_b.html
== upper_id_attr.html upper_id_attr_ref.html
# inline_border_a.html inline_border_b.html
== anon_block_inherit_a.html anon_block_inherit_b.html