diff options
author | Glenn Watson <gw@intuitionlibrary.com> | 2015-01-29 14:09:43 +1000 |
---|---|---|
committer | Glenn Watson <gw@intuitionlibrary.com> | 2015-01-29 16:36:20 +1000 |
commit | 1f37c6eabe3237da68014644c1144a04e6f69037 (patch) | |
tree | bc2af2b8f29aa0b8bae93d3f9e91d10e550180cd | |
parent | 221a343883f510c7743908136438f5ed40bd17ed (diff) | |
download | servo-1f37c6eabe3237da68014644c1144a04e6f69037.tar.gz servo-1f37c6eabe3237da68014644c1144a04e6f69037.zip |
Add layout support and tests for inline iframes. Fixes #1697.
-rw-r--r-- | components/layout/construct.rs | 1 | ||||
-rw-r--r-- | components/layout/fragment.rs | 111 | ||||
-rw-r--r-- | tests/ref/basic.list | 7 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_default.html | 9 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_default_ref.html | 7 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_height.html | 9 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_height_ref.html | 7 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_max.html | 9 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_max_ref.html | 7 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_min.html | 9 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_min_ref.html | 7 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_width.html | 9 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_width_height.html | 9 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_width_height_ref.html | 7 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_width_percentage.html | 9 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_width_percentage_ref.html | 7 | ||||
-rw-r--r-- | tests/ref/iframe/simple_inline_width_ref.html | 7 |
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> |