mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Add layout support and tests for inline iframes. Fixes #1697.
This commit is contained in:
parent
221a343883
commit
1f37c6eabe
17 changed files with 200 additions and 31 deletions
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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,8 +425,7 @@ impl ReplacedImageFragmentInfo {
|
|||
MaybeAuto::Auto => intrinsic_height,
|
||||
MaybeAuto::Specified(h) => h,
|
||||
};
|
||||
let specified_height = ReplacedImageFragmentInfo::clamp_size(
|
||||
specified_height,
|
||||
let specified_height = clamp_size(specified_height,
|
||||
style_min_block_size,
|
||||
style_max_block_size,
|
||||
Au(0));
|
||||
|
@ -436,7 +435,7 @@ impl ReplacedImageFragmentInfo {
|
|||
MaybeAuto::Specified(w) => w,
|
||||
};
|
||||
|
||||
let inline_size = ReplacedImageFragmentInfo::clamp_size(inline_size,
|
||||
let inline_size = clamp_size(inline_size,
|
||||
style_min_inline_size,
|
||||
style_max_inline_size,
|
||||
container_inline_size);
|
||||
|
@ -475,7 +474,7 @@ impl ReplacedImageFragmentInfo {
|
|||
}
|
||||
};
|
||||
|
||||
let block_size = ReplacedImageFragmentInfo::clamp_size(block_size,
|
||||
let block_size = clamp_size(block_size,
|
||||
style_min_block_size,
|
||||
style_max_block_size,
|
||||
Au(0));
|
||||
|
@ -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"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
9
tests/ref/iframe/simple_inline_default.html
Normal file
9
tests/ref/iframe/simple_inline_default.html
Normal file
|
@ -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>
|
7
tests/ref/iframe/simple_inline_default_ref.html
Normal file
7
tests/ref/iframe/simple_inline_default_ref.html
Normal file
|
@ -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>
|
9
tests/ref/iframe/simple_inline_height.html
Normal file
9
tests/ref/iframe/simple_inline_height.html
Normal file
|
@ -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>
|
7
tests/ref/iframe/simple_inline_height_ref.html
Normal file
7
tests/ref/iframe/simple_inline_height_ref.html
Normal file
|
@ -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>
|
9
tests/ref/iframe/simple_inline_max.html
Normal file
9
tests/ref/iframe/simple_inline_max.html
Normal file
|
@ -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>
|
7
tests/ref/iframe/simple_inline_max_ref.html
Normal file
7
tests/ref/iframe/simple_inline_max_ref.html
Normal file
|
@ -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>
|
9
tests/ref/iframe/simple_inline_min.html
Normal file
9
tests/ref/iframe/simple_inline_min.html
Normal file
|
@ -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>
|
7
tests/ref/iframe/simple_inline_min_ref.html
Normal file
7
tests/ref/iframe/simple_inline_min_ref.html
Normal file
|
@ -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>
|
9
tests/ref/iframe/simple_inline_width.html
Normal file
9
tests/ref/iframe/simple_inline_width.html
Normal file
|
@ -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>
|
9
tests/ref/iframe/simple_inline_width_height.html
Normal file
9
tests/ref/iframe/simple_inline_width_height.html
Normal file
|
@ -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>
|
7
tests/ref/iframe/simple_inline_width_height_ref.html
Normal file
7
tests/ref/iframe/simple_inline_width_height_ref.html
Normal file
|
@ -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>
|
9
tests/ref/iframe/simple_inline_width_percentage.html
Normal file
9
tests/ref/iframe/simple_inline_width_percentage.html
Normal file
|
@ -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>
|
7
tests/ref/iframe/simple_inline_width_percentage_ref.html
Normal file
7
tests/ref/iframe/simple_inline_width_percentage_ref.html
Normal file
|
@ -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>
|
7
tests/ref/iframe/simple_inline_width_ref.html
Normal file
7
tests/ref/iframe/simple_inline_width_ref.html
Normal file
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue