aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/construct.rs
diff options
context:
space:
mode:
authorMatt Brubeck <mbrubeck@limpet.net>2016-04-15 15:57:24 -0700
committerMatt Brubeck <mbrubeck@limpet.net>2016-04-16 11:01:40 -0700
commit1807fd3cc5741e410b7eae4eb4c2f389c594b144 (patch)
tree675816d6286e1dd3e81bd3139bef2360b0ee48a4 /components/layout/construct.rs
parentfbef2724bf12c2204f0256cebaa5a4d0e8ef45f2 (diff)
downloadservo-1807fd3cc5741e410b7eae4eb4c2f389c594b144.tar.gz
servo-1807fd3cc5741e410b7eae4eb4c2f389c594b144.zip
Generate a fragment for an empty elements with borders or padding
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r--components/layout/construct.rs43
1 files changed, 41 insertions, 2 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 8bf1a416484..dd8b7ec0756 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -13,6 +13,7 @@
#![deny(unsafe_code)]
+use app_units::Au;
use block::BlockFlow;
use context::LayoutContext;
use data::{HAS_NEWLY_CONSTRUCTED_FLOW, PrivateLayoutData};
@@ -808,7 +809,9 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
let mut abs_descendants = AbsoluteDescendants::new();
// Concatenate all the fragments of our kids, creating {ib} splits as necessary.
+ let mut is_empty = true;
for kid in node.children() {
+ is_empty = false;
if kid.get_pseudo_element_type() != PseudoElementType::Normal {
self.process(&kid);
}
@@ -889,6 +892,22 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
}
}
+ if is_empty && node.style().has_padding_or_border() {
+ // An empty inline box needs at least one fragment to draw its background and borders.
+ let info = SpecificFragmentInfo::UnscannedText(
+ box UnscannedTextFragmentInfo::new(String::new(), None));
+ let mut modified_style = node.style().clone();
+ properties::modify_style_for_replaced_content(&mut modified_style);
+ properties::modify_style_for_text(&mut modified_style);
+ let fragment = Fragment::from_opaque_node_and_style(node.opaque(),
+ node.get_pseudo_element_type().strip(),
+ modified_style,
+ node.selected_style().clone(),
+ node.restyle_damage(),
+ info);
+ fragment_accumulator.fragments.fragments.push_back(fragment)
+ }
+
// Finally, make a new construction result.
if opt_inline_block_splits.len() > 0 || !fragment_accumulator.fragments.is_empty()
|| abs_descendants.len() > 0 {
@@ -923,8 +942,6 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
}
// If this node is ignorable whitespace, bail out now.
- //
- // FIXME(#2001, pcwalton): Don't do this if there's padding or borders.
if node.is_ignorable_whitespace() {
return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
node.opaque(),
@@ -1852,3 +1869,25 @@ fn control_chars_to_fragment(node: &InlineFragmentNodeInfo,
restyle_damage,
info)
}
+
+/// Convenience methods for computed CSS values
+trait ComputedValueUtils {
+ /// Returns true if this node has non-zero padding or border.
+ fn has_padding_or_border(&self) -> bool;
+}
+
+impl ComputedValueUtils for ServoComputedValues {
+ fn has_padding_or_border(&self) -> bool {
+ let padding = self.get_padding();
+ let border = self.get_border();
+
+ !padding.padding_top.is_definitely_zero() ||
+ !padding.padding_right.is_definitely_zero() ||
+ !padding.padding_bottom.is_definitely_zero() ||
+ !padding.padding_left.is_definitely_zero() ||
+ border.border_top_width != Au(0) ||
+ border.border_right_width != Au(0) ||
+ border.border_bottom_width != Au(0) ||
+ border.border_left_width != Au(0)
+ }
+}