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() { 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 { impl Box {
/// Constructs a new `Box` instance. /// Constructs a new `Box` instance.
pub fn new(node: LayoutNode, specific: SpecificBoxInfo) -> Box { 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 { Box {
node: OpaqueNode::from_layout_node(&node), node: OpaqueNode::from_layout_node(&node),
style: node_style, style: node.style().clone(),
position: RefCell::new(Au::zero_rect()), position: RefCell::new(Au::zero_rect()),
border: RefCell::new(Zero::zero()), border: RefCell::new(Zero::zero()),
padding: RefCell::new(Zero::zero()), padding: RefCell::new(Zero::zero()),

View file

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

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 == img_size_a.html img_size_b.html
== upper_id_attr.html upper_id_attr_ref.html == upper_id_attr.html upper_id_attr_ref.html
# inline_border_a.html inline_border_b.html # inline_border_a.html inline_border_b.html
== anon_block_inherit_a.html anon_block_inherit_b.html