mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
layout: Allow inline elements to be containing blocks for
absolutely-positioned elements. This also implements a little bit of the infrastructure needed to support for fragmentation via support for multiple positioned fragments in one flow. Improves Google.
This commit is contained in:
parent
b3b9deafa7
commit
1f0b5889da
19 changed files with 592 additions and 241 deletions
|
@ -149,6 +149,11 @@ pub enum SpecificFragmentInfo {
|
|||
InlineAbsoluteHypothetical(InlineAbsoluteHypotheticalFragmentInfo),
|
||||
|
||||
InlineBlock(InlineBlockFragmentInfo),
|
||||
|
||||
/// An inline fragment that establishes an absolute containing block for its descendants (i.e.
|
||||
/// a positioned inline fragment).
|
||||
InlineAbsolute(InlineAbsoluteFragmentInfo),
|
||||
|
||||
ScannedText(Box<ScannedTextFragmentInfo>),
|
||||
Table,
|
||||
TableCell,
|
||||
|
@ -175,6 +180,7 @@ impl SpecificFragmentInfo {
|
|||
SpecificFragmentInfo::UnscannedText(_) |
|
||||
SpecificFragmentInfo::Generic => return RestyleDamage::empty(),
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => &info.flow_ref,
|
||||
SpecificFragmentInfo::InlineAbsolute(ref info) => &info.flow_ref,
|
||||
SpecificFragmentInfo::InlineBlock(ref info) => &info.flow_ref,
|
||||
};
|
||||
|
||||
|
@ -188,6 +194,7 @@ impl SpecificFragmentInfo {
|
|||
SpecificFragmentInfo::GeneratedContent(_) => "SpecificFragmentInfo::GeneratedContent",
|
||||
SpecificFragmentInfo::Iframe(_) => "SpecificFragmentInfo::Iframe",
|
||||
SpecificFragmentInfo::Image(_) => "SpecificFragmentInfo::Image",
|
||||
SpecificFragmentInfo::InlineAbsolute(_) => "SpecificFragmentInfo::InlineAbsolute",
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
|
||||
"SpecificFragmentInfo::InlineAbsoluteHypothetical"
|
||||
}
|
||||
|
@ -260,6 +267,24 @@ impl InlineBlockFragmentInfo {
|
|||
}
|
||||
}
|
||||
|
||||
/// An inline fragment that establishes an absolute containing block for its descendants (i.e.
|
||||
/// a positioned inline fragment).
|
||||
///
|
||||
/// FIXME(pcwalton): Stop leaking this `FlowRef` to layout; that is not memory safe because layout
|
||||
/// can clone it.
|
||||
#[derive(Clone)]
|
||||
pub struct InlineAbsoluteFragmentInfo {
|
||||
pub flow_ref: FlowRef,
|
||||
}
|
||||
|
||||
impl InlineAbsoluteFragmentInfo {
|
||||
pub fn new(flow_ref: FlowRef) -> InlineAbsoluteFragmentInfo {
|
||||
InlineAbsoluteFragmentInfo {
|
||||
flow_ref: flow_ref,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CanvasFragmentInfo {
|
||||
pub replaced_image_fragment_info: ReplacedImageFragmentInfo,
|
||||
|
@ -868,7 +893,8 @@ impl Fragment {
|
|||
SpecificFragmentInfo::Generic |
|
||||
SpecificFragmentInfo::GeneratedContent(_) |
|
||||
SpecificFragmentInfo::Iframe(_) |
|
||||
SpecificFragmentInfo::Image(_) => {
|
||||
SpecificFragmentInfo::Image(_) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) => {
|
||||
QuantitiesIncludedInIntrinsicInlineSizes::all()
|
||||
}
|
||||
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell => {
|
||||
|
@ -1247,6 +1273,10 @@ impl Fragment {
|
|||
let block_flow = info.flow_ref.as_block();
|
||||
result.union_block(&block_flow.base.intrinsic_inline_sizes)
|
||||
}
|
||||
SpecificFragmentInfo::InlineAbsolute(ref mut info) => {
|
||||
let block_flow = info.flow_ref.as_block();
|
||||
result.union_block(&block_flow.base.intrinsic_inline_sizes)
|
||||
}
|
||||
SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
|
||||
let image_inline_size = match image_fragment_info.replaced_image_fragment_info
|
||||
.dom_inline_size {
|
||||
|
@ -1318,7 +1348,8 @@ impl Fragment {
|
|||
SpecificFragmentInfo::TableRow |
|
||||
SpecificFragmentInfo::TableWrapper |
|
||||
SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => Au(0),
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) => Au(0),
|
||||
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
|
||||
canvas_fragment_info.replaced_image_fragment_info.computed_inline_size()
|
||||
}
|
||||
|
@ -1608,6 +1639,7 @@ impl Fragment {
|
|||
SpecificFragmentInfo::Iframe(_) |
|
||||
SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||
SpecificFragmentInfo::ScannedText(_) => {}
|
||||
};
|
||||
|
||||
|
@ -1631,6 +1663,14 @@ impl Fragment {
|
|||
block_flow.base.block_container_inline_size = self.border_box.size.inline;
|
||||
block_flow.base.block_container_writing_mode = self.style.writing_mode;
|
||||
}
|
||||
SpecificFragmentInfo::InlineAbsolute(ref mut info) => {
|
||||
let block_flow = info.flow_ref.as_block();
|
||||
self.border_box.size.inline =
|
||||
max(block_flow.base.intrinsic_inline_sizes.minimum_inline_size,
|
||||
block_flow.base.intrinsic_inline_sizes.preferred_inline_size);
|
||||
block_flow.base.block_container_inline_size = self.border_box.size.inline;
|
||||
block_flow.base.block_container_writing_mode = self.style.writing_mode;
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref info) => {
|
||||
// Scanned text fragments will have already had their content inline-sizes assigned
|
||||
// by this point.
|
||||
|
@ -1690,6 +1730,7 @@ impl Fragment {
|
|||
SpecificFragmentInfo::Image(_) |
|
||||
SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||
SpecificFragmentInfo::ScannedText(_) => {}
|
||||
}
|
||||
|
||||
|
@ -1735,6 +1776,12 @@ impl Fragment {
|
|||
let block_flow = info.flow_ref.as_block();
|
||||
self.border_box.size.block = block_flow.base.position.size.block;
|
||||
}
|
||||
SpecificFragmentInfo::InlineAbsolute(ref mut info) => {
|
||||
// Not the primary fragment, so we do not take the noncontent size into account.
|
||||
let block_flow = info.flow_ref.as_block();
|
||||
self.border_box.size.block = block_flow.base.position.size.block +
|
||||
block_flow.fragment.margin.block_start_end()
|
||||
}
|
||||
SpecificFragmentInfo::Iframe(_) => {
|
||||
self.border_box.size.block = IframeFragmentInfo::calculate_replaced_block_size(
|
||||
style, containing_block_block_size) +
|
||||
|
@ -1774,7 +1821,8 @@ impl Fragment {
|
|||
block_flow.fragment.margin.block_start,
|
||||
block_flow.fragment.margin.block_end)
|
||||
}
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) => {
|
||||
// Hypothetical boxes take up no space.
|
||||
InlineMetrics {
|
||||
block_size_above_baseline: Au(0),
|
||||
|
@ -1829,6 +1877,7 @@ impl Fragment {
|
|||
match self.specific {
|
||||
SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::InlineAbsolute(_) |
|
||||
SpecificFragmentInfo::TableWrapper => false,
|
||||
SpecificFragmentInfo::Canvas(_) |
|
||||
SpecificFragmentInfo::Generic |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue