aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorGlenn Watson <gw@intuitionlibrary.com>2015-01-29 14:09:43 +1000
committerGlenn Watson <gw@intuitionlibrary.com>2015-01-29 16:36:20 +1000
commit1f37c6eabe3237da68014644c1144a04e6f69037 (patch)
treebc2af2b8f29aa0b8bae93d3f9e91d10e550180cd /components
parent221a343883f510c7743908136438f5ed40bd17ed (diff)
downloadservo-1f37c6eabe3237da68014644c1144a04e6f69037.tar.gz
servo-1f37c6eabe3237da68014644c1144a04e6f69037.zip
Add layout support and tests for inline iframes. Fixes #1697.
Diffstat (limited to 'components')
-rw-r--r--components/layout/construct.rs1
-rw-r--r--components/layout/fragment.rs111
2 files changed, 81 insertions, 31 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 58fe265d54d..eb241630dba 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -1306,6 +1306,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
None |
Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLImageElement))) => true,
Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement))) => self.has_object_data(),
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement))) => true,
Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLCanvasElement))) => true,
Some(NodeTypeId::Element(_)) => false,
}
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 8dcf24b8bee..281eeaaa5d2 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -194,6 +194,18 @@ impl SpecificFragmentInfo {
}
}
+/// Clamp a value obtained from style_length, based on min / max lengths.
+fn clamp_size(size: Au, min_size: LengthOrPercentage, max_size: LengthOrPercentageOrNone,
+ container_inline_size: Au) -> Au {
+ let min_size = model::specified(min_size, container_inline_size);
+ let max_size = model::specified_or_none(max_size, container_inline_size);
+
+ Au::max(min_size, match max_size {
+ None => size,
+ Some(max_size) => Au::min(size, max_size),
+ })
+}
+
/// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was declared
/// with `display: inline;`.
///
@@ -375,18 +387,6 @@ impl ReplacedImageFragmentInfo {
}
}
- /// Clamp a value obtained from style_length, based on min / max lengths.
- pub fn clamp_size(size: Au, min_size: LengthOrPercentage, max_size: LengthOrPercentageOrNone,
- container_inline_size: Au) -> Au {
- let min_size = model::specified(min_size, container_inline_size);
- let max_size = model::specified_or_none(max_size, container_inline_size);
-
- Au::max(min_size, match max_size {
- None => size,
- Some(max_size) => Au::min(size, max_size),
- })
- }
-
pub fn calculate_replaced_inline_size(&mut self,
style: ComputedValues,
noncontent_inline_size: Au,
@@ -425,21 +425,20 @@ impl ReplacedImageFragmentInfo {
MaybeAuto::Auto => intrinsic_height,
MaybeAuto::Specified(h) => h,
};
- let specified_height = ReplacedImageFragmentInfo::clamp_size(
- specified_height,
- style_min_block_size,
- style_max_block_size,
- Au(0));
+ let specified_height = clamp_size(specified_height,
+ style_min_block_size,
+ style_max_block_size,
+ Au(0));
Au((specified_height.to_f32().unwrap() * ratio) as i32)
}
},
MaybeAuto::Specified(w) => w,
};
- let inline_size = ReplacedImageFragmentInfo::clamp_size(inline_size,
- style_min_inline_size,
- style_max_inline_size,
- container_inline_size);
+ let inline_size = clamp_size(inline_size,
+ style_min_inline_size,
+ style_max_inline_size,
+ container_inline_size);
self.computed_inline_size = Some(inline_size);
inline_size + noncontent_inline_size
@@ -475,10 +474,10 @@ impl ReplacedImageFragmentInfo {
}
};
- let block_size = ReplacedImageFragmentInfo::clamp_size(block_size,
- style_min_block_size,
- style_max_block_size,
- Au(0));
+ let block_size = clamp_size(block_size,
+ style_min_block_size,
+ style_max_block_size,
+ Au(0));
self.computed_block_size = Some(block_size);
block_size + noncontent_block_size
@@ -504,6 +503,44 @@ impl IframeFragmentInfo {
subpage_id: subpage_id,
}
}
+
+ #[inline]
+ pub fn calculate_replaced_inline_size(style: ComputedValues, containing_size: Au) -> Au {
+ // Calculate the replaced inline size (or default) as per CSS 2.1 § 10.3.2
+ IframeFragmentInfo::calculate_replaced_size(style.content_inline_size(),
+ style.min_inline_size(),
+ style.max_inline_size(),
+ containing_size,
+ Au::from_px(300))
+ }
+
+ #[inline]
+ pub fn calculate_replaced_block_size(style: ComputedValues, containing_size: Au) -> Au {
+ // Calculate the replaced block size (or default) as per CSS 2.1 § 10.3.2
+ IframeFragmentInfo::calculate_replaced_size(style.content_block_size(),
+ style.min_block_size(),
+ style.max_block_size(),
+ containing_size,
+ Au::from_px(150))
+
+ }
+
+ fn calculate_replaced_size(content_size: LengthOrPercentageOrAuto,
+ style_min_size: LengthOrPercentage,
+ style_max_size: LengthOrPercentageOrNone,
+ containing_size: Au, default_size: Au) -> Au {
+ let computed_size = match MaybeAuto::from_style(content_size, containing_size) {
+ MaybeAuto::Specified(length) => length,
+ MaybeAuto::Auto => default_size,
+ };
+
+ let size = clamp_size(computed_size,
+ style_min_size,
+ style_max_size,
+ containing_size);
+
+ size
+ }
}
/// A scanned text fragment represents a single run of text with a distinct style. A `TextFragment`
@@ -1171,8 +1208,10 @@ impl Fragment {
pub fn compute_intrinsic_inline_sizes(&mut self) -> IntrinsicISizesContribution {
let mut result = self.style_specified_intrinsic_inline_size();
match self.specific {
- SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
- SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper |
+ SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) |
+ SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+ SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow |
+ SpecificFragmentInfo::TableWrapper |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
SpecificFragmentInfo::InlineBlock(ref mut info) => {
let block_flow = info.flow_ref.as_block();
@@ -1543,14 +1582,14 @@ impl Fragment {
/// content per CSS 2.1 § 10.3.2.
pub fn assign_replaced_inline_size_if_necessary<'a>(&'a mut self, container_inline_size: Au) {
match self.specific {
- SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+ SpecificFragmentInfo::Generic | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
- SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
+ SpecificFragmentInfo::InlineAbsoluteHypothetical(_) | SpecificFragmentInfo::Iframe(_) => {}
};
let style = self.style().clone();
@@ -1596,6 +1635,11 @@ impl Fragment {
fragment_inline_size,
fragment_block_size);
}
+ SpecificFragmentInfo::Iframe(_) => {
+ self.border_box.size.inline = IframeFragmentInfo::calculate_replaced_inline_size(
+ style, container_inline_size) +
+ noncontent_inline_size;
+ }
_ => panic!("this case should have been handled above"),
}
}
@@ -1606,14 +1650,14 @@ impl Fragment {
/// Ideally, this should follow CSS 2.1 § 10.6.2.
pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
match self.specific {
- SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
+ SpecificFragmentInfo::Generic | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have block_size"),
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
- SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
+ SpecificFragmentInfo::InlineAbsoluteHypothetical(_) | SpecificFragmentInfo::Iframe(_) => {}
}
let style = self.style().clone();
@@ -1656,6 +1700,11 @@ impl Fragment {
let block_flow = info.flow_ref.as_block();
self.border_box.size.block = block_flow.base.position.size.block;
}
+ SpecificFragmentInfo::Iframe(_) => {
+ self.border_box.size.block = IframeFragmentInfo::calculate_replaced_block_size(
+ style, containing_block_block_size) +
+ noncontent_block_size;
+ }
_ => panic!("should have been handled above"),
}
}