aboutsummaryrefslogtreecommitdiffstats
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
parent221a343883f510c7743908136438f5ed40bd17ed (diff)
downloadservo-1f37c6eabe3237da68014644c1144a04e6f69037.tar.gz
servo-1f37c6eabe3237da68014644c1144a04e6f69037.zip
Add layout support and tests for inline iframes. Fixes #1697.
-rw-r--r--components/layout/construct.rs1
-rw-r--r--components/layout/fragment.rs111
-rw-r--r--tests/ref/basic.list7
-rw-r--r--tests/ref/iframe/simple_inline_default.html9
-rw-r--r--tests/ref/iframe/simple_inline_default_ref.html7
-rw-r--r--tests/ref/iframe/simple_inline_height.html9
-rw-r--r--tests/ref/iframe/simple_inline_height_ref.html7
-rw-r--r--tests/ref/iframe/simple_inline_max.html9
-rw-r--r--tests/ref/iframe/simple_inline_max_ref.html7
-rw-r--r--tests/ref/iframe/simple_inline_min.html9
-rw-r--r--tests/ref/iframe/simple_inline_min_ref.html7
-rw-r--r--tests/ref/iframe/simple_inline_width.html9
-rw-r--r--tests/ref/iframe/simple_inline_width_height.html9
-rw-r--r--tests/ref/iframe/simple_inline_width_height_ref.html7
-rw-r--r--tests/ref/iframe/simple_inline_width_percentage.html9
-rw-r--r--tests/ref/iframe/simple_inline_width_percentage_ref.html7
-rw-r--r--tests/ref/iframe/simple_inline_width_ref.html7
17 files changed, 200 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"),
}
}
diff --git a/tests/ref/basic.list b/tests/ref/basic.list
index efc0814758f..281a854d2d1 100644
--- a/tests/ref/basic.list
+++ b/tests/ref/basic.list
@@ -126,6 +126,13 @@ fragment=top != ../html/acid2.html acid2_ref.html
== multiple_css_class_a.html multiple_css_class_b.html
== iframe/simple.html iframe/simple_ref.html
+== iframe/simple_inline_default.html iframe/simple_inline_default_ref.html
+== iframe/simple_inline_width.html iframe/simple_inline_width_ref.html
+== iframe/simple_inline_width_height.html iframe/simple_inline_width_height_ref.html
+== iframe/simple_inline_height.html iframe/simple_inline_height_ref.html
+== iframe/simple_inline_width_percentage.html iframe/simple_inline_width_percentage_ref.html
+== iframe/simple_inline_min.html iframe/simple_inline_min_ref.html
+== iframe/simple_inline_max.html iframe/simple_inline_max_ref.html
== iframe/multiple_external.html iframe/multiple_external_ref.html
== iframe/overflow.html iframe/overflow_ref.html
== iframe/positioning_margin.html iframe/positioning_margin_ref.html
diff --git a/tests/ref/iframe/simple_inline_default.html b/tests/ref/iframe/simple_inline_default.html
new file mode 100644
index 00000000000..c4d268304f5
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_default.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <div style="margin-top: 20px;">
+ <iframe src="data:text/html,%3Cspan%3EJust%20a%20simple%20little%20iframe.%3C%2Fspan%3E"
+ style="display: inline; border: 1px solid black;">
+ </iframe>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_default_ref.html b/tests/ref/iframe/simple_inline_default_ref.html
new file mode 100644
index 00000000000..ad8e4eb5063
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_default_ref.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+ <div style="border: 1px solid black; width: 300px; height: 150px; margin-top: 20px;">
+ <div style="margin: 8px; /* matches user-agent body */">Just a simple little iframe.</div>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_height.html b/tests/ref/iframe/simple_inline_height.html
new file mode 100644
index 00000000000..be28febf1ef
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_height.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <div style="margin-top: 20px;">
+ <iframe src="data:text/html,%3Cspan%3EJust%20a%20simple%20little%20iframe.%3C%2Fspan%3E"
+ style="display: inline; border: 1px solid black; height: 300px;">
+ </iframe>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_height_ref.html b/tests/ref/iframe/simple_inline_height_ref.html
new file mode 100644
index 00000000000..7d3c09396da
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_height_ref.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+ <div style="border: 1px solid black; width: 300px; height: 300px; margin-top: 20px;">
+ <div style="margin: 8px; /* matches user-agent body */">Just a simple little iframe.</div>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_max.html b/tests/ref/iframe/simple_inline_max.html
new file mode 100644
index 00000000000..fb1a075247a
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_max.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <div style="margin-top: 20px;">
+ <iframe src="data:text/html,%3Cspan%3EJust%20a%20simple%20little%20iframe.%3C%2Fspan%3E"
+ style="display: inline; border: 1px solid black; max-width: 250px; max-height: 50px;">
+ </iframe>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_max_ref.html b/tests/ref/iframe/simple_inline_max_ref.html
new file mode 100644
index 00000000000..63c1cf61cc9
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_max_ref.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+ <div style="border: 1px solid black; width: 250px; height: 50px; margin-top: 20px;">
+ <div style="margin: 8px; /* matches user-agent body */">Just a simple little iframe.</div>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_min.html b/tests/ref/iframe/simple_inline_min.html
new file mode 100644
index 00000000000..e8466c5d570
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_min.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <div style="margin-top: 20px;">
+ <iframe src="data:text/html,%3Cspan%3EJust%20a%20simple%20little%20iframe.%3C%2Fspan%3E"
+ style="display: inline; border: 1px solid black; min-width: 400px; min-height: 250px;">
+ </iframe>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_min_ref.html b/tests/ref/iframe/simple_inline_min_ref.html
new file mode 100644
index 00000000000..43d27a8721a
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_min_ref.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+ <div style="border: 1px solid black; width: 400px; height: 250px; margin-top: 20px;">
+ <div style="margin: 8px; /* matches user-agent body */">Just a simple little iframe.</div>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_width.html b/tests/ref/iframe/simple_inline_width.html
new file mode 100644
index 00000000000..3020f65ca52
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_width.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <div style="margin-top: 20px;">
+ <iframe src="data:text/html,%3Cspan%3EJust%20a%20simple%20little%20iframe.%3C%2Fspan%3E"
+ style="display: inline; border: 1px solid black; width: 500px;">
+ </iframe>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_width_height.html b/tests/ref/iframe/simple_inline_width_height.html
new file mode 100644
index 00000000000..1c419a30c1d
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_width_height.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <div style="margin-top: 20px;">
+ <iframe src="data:text/html,%3Cspan%3EJust%20a%20simple%20little%20iframe.%3C%2Fspan%3E"
+ style="display: inline; border: 1px solid black; width: 500px; height: 300px;">
+ </iframe>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_width_height_ref.html b/tests/ref/iframe/simple_inline_width_height_ref.html
new file mode 100644
index 00000000000..f673586b9a0
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_width_height_ref.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+ <div style="border: 1px solid black; width: 500px; height: 300px; margin-top: 20px;">
+ <div style="margin: 8px; /* matches user-agent body */">Just a simple little iframe.</div>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_width_percentage.html b/tests/ref/iframe/simple_inline_width_percentage.html
new file mode 100644
index 00000000000..29b55c2b683
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_width_percentage.html
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <div style="margin-top: 20px; width: 400px;">
+ <iframe src="data:text/html,%3Cspan%3EJust%20a%20simple%20little%20iframe.%3C%2Fspan%3E"
+ style="display: inline; border: 1px solid black; width: 50%;">
+ </iframe>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_width_percentage_ref.html b/tests/ref/iframe/simple_inline_width_percentage_ref.html
new file mode 100644
index 00000000000..40009128650
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_width_percentage_ref.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+ <div style="border: 1px solid black; width: 200px; height: 150px; margin-top: 20px;">
+ <div style="margin: 8px; /* matches user-agent body */">Just a simple little iframe.</div>
+ </div>
+</body>
+</html>
diff --git a/tests/ref/iframe/simple_inline_width_ref.html b/tests/ref/iframe/simple_inline_width_ref.html
new file mode 100644
index 00000000000..0998c2054be
--- /dev/null
+++ b/tests/ref/iframe/simple_inline_width_ref.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+ <div style="border: 1px solid black; width: 500px; height: 150px; margin-top: 20px;">
+ <div style="margin: 8px; /* matches user-agent body */">Just a simple little iframe.</div>
+ </div>
+</body>
+</html>