mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Remove the Node type parameter from Contents
We now pass the Node as an argument during DOM traversal in layout.
This commit is contained in:
parent
b2f6cc7144
commit
47944a39fc
6 changed files with 114 additions and 63 deletions
|
@ -24,9 +24,9 @@ pub enum WhichPseudoElement {
|
||||||
After,
|
After,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) enum Contents<Node> {
|
pub(super) enum Contents {
|
||||||
/// Refers to a DOM subtree, plus `::before` and `::after` pseudo-elements.
|
/// Refers to a DOM subtree, plus `::before` and `::after` pseudo-elements.
|
||||||
OfElement(Node),
|
OfElement,
|
||||||
|
|
||||||
/// Example: an `<img src=…>` element.
|
/// Example: an `<img src=…>` element.
|
||||||
/// <https://drafts.csswg.org/css2/conform.html#replaced-element>
|
/// <https://drafts.csswg.org/css2/conform.html#replaced-element>
|
||||||
|
@ -37,8 +37,8 @@ pub(super) enum Contents<Node> {
|
||||||
OfPseudoElement(Vec<PseudoElementContentItem>),
|
OfPseudoElement(Vec<PseudoElementContentItem>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) enum NonReplacedContents<Node> {
|
pub(super) enum NonReplacedContents {
|
||||||
OfElement(Node),
|
OfElement,
|
||||||
OfPseudoElement(Vec<PseudoElementContentItem>),
|
OfPseudoElement(Vec<PseudoElementContentItem>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,9 +56,10 @@ where
|
||||||
/// Or pseudo-element
|
/// Or pseudo-element
|
||||||
fn handle_element(
|
fn handle_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
node: Node,
|
||||||
style: &ServoArc<ComputedValues>,
|
style: &ServoArc<ComputedValues>,
|
||||||
display: DisplayGeneratingBox,
|
display: DisplayGeneratingBox,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -108,9 +109,10 @@ fn traverse_element<'dom, Node>(
|
||||||
},
|
},
|
||||||
Display::GeneratingBox(display) => {
|
Display::GeneratingBox(display) => {
|
||||||
handler.handle_element(
|
handler.handle_element(
|
||||||
|
element,
|
||||||
&style,
|
&style,
|
||||||
display,
|
display,
|
||||||
replaced.map_or(Contents::OfElement(element), Contents::Replaced),
|
replaced.map_or(Contents::OfElement, Contents::Replaced),
|
||||||
element.element_box_slot(),
|
element.element_box_slot(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -131,19 +133,20 @@ fn traverse_pseudo_element<'dom, Node>(
|
||||||
Display::Contents => {
|
Display::Contents => {
|
||||||
element.unset_pseudo_element_box(which);
|
element.unset_pseudo_element_box(which);
|
||||||
let items = generate_pseudo_element_content(&style, element, context);
|
let items = generate_pseudo_element_content(&style, element, context);
|
||||||
traverse_pseudo_element_contents(&style, context, handler, items);
|
traverse_pseudo_element_contents(element, &style, context, handler, items);
|
||||||
},
|
},
|
||||||
Display::GeneratingBox(display) => {
|
Display::GeneratingBox(display) => {
|
||||||
let items = generate_pseudo_element_content(&style, element, context);
|
let items = generate_pseudo_element_content(&style, element, context);
|
||||||
let contents = Contents::OfPseudoElement(items);
|
let contents = Contents::OfPseudoElement(items);
|
||||||
let box_slot = element.pseudo_element_box_slot(which);
|
let box_slot = element.pseudo_element_box_slot(which);
|
||||||
handler.handle_element(&style, display, contents, box_slot);
|
handler.handle_element(element, &style, display, contents, box_slot);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn traverse_pseudo_element_contents<'dom, Node>(
|
fn traverse_pseudo_element_contents<'dom, Node>(
|
||||||
|
node: Node,
|
||||||
pseudo_element_style: &ServoArc<ComputedValues>,
|
pseudo_element_style: &ServoArc<ComputedValues>,
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
handler: &mut impl TraversalHandler<'dom, Node>,
|
handler: &mut impl TraversalHandler<'dom, Node>,
|
||||||
|
@ -176,6 +179,7 @@ fn traverse_pseudo_element_contents<'dom, Node>(
|
||||||
Display::GeneratingBox(display_inline)
|
Display::GeneratingBox(display_inline)
|
||||||
);
|
);
|
||||||
handler.handle_element(
|
handler.handle_element(
|
||||||
|
node,
|
||||||
item_style,
|
item_style,
|
||||||
display_inline,
|
display_inline,
|
||||||
Contents::Replaced(contents),
|
Contents::Replaced(contents),
|
||||||
|
@ -187,51 +191,51 @@ fn traverse_pseudo_element_contents<'dom, Node>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node> Contents<Node> {
|
impl Contents {
|
||||||
/// Returns true iff the `try_from` impl below would return `Err(_)`
|
/// Returns true iff the `try_from` impl below would return `Err(_)`
|
||||||
pub fn is_replaced(&self) -> bool {
|
pub fn is_replaced(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Contents::OfElement(_) | Contents::OfPseudoElement(_) => false,
|
Contents::OfElement | Contents::OfPseudoElement(_) => false,
|
||||||
Contents::Replaced(_) => true,
|
Contents::Replaced(_) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node> std::convert::TryFrom<Contents<Node>> for NonReplacedContents<Node> {
|
impl std::convert::TryFrom<Contents> for NonReplacedContents {
|
||||||
type Error = ReplacedContent;
|
type Error = ReplacedContent;
|
||||||
|
|
||||||
fn try_from(contents: Contents<Node>) -> Result<Self, Self::Error> {
|
fn try_from(contents: Contents) -> Result<Self, Self::Error> {
|
||||||
match contents {
|
match contents {
|
||||||
Contents::OfElement(node) => Ok(NonReplacedContents::OfElement(node)),
|
Contents::OfElement => Ok(NonReplacedContents::OfElement),
|
||||||
Contents::OfPseudoElement(items) => Ok(NonReplacedContents::OfPseudoElement(items)),
|
Contents::OfPseudoElement(items) => Ok(NonReplacedContents::OfPseudoElement(items)),
|
||||||
Contents::Replaced(replaced) => Err(replaced),
|
Contents::Replaced(replaced) => Err(replaced),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node> std::convert::From<NonReplacedContents<Node>> for Contents<Node> {
|
impl From<NonReplacedContents> for Contents {
|
||||||
fn from(contents: NonReplacedContents<Node>) -> Self {
|
fn from(contents: NonReplacedContents) -> Self {
|
||||||
match contents {
|
match contents {
|
||||||
NonReplacedContents::OfElement(node) => Contents::OfElement(node),
|
NonReplacedContents::OfElement => Contents::OfElement,
|
||||||
NonReplacedContents::OfPseudoElement(items) => Contents::OfPseudoElement(items),
|
NonReplacedContents::OfPseudoElement(items) => Contents::OfPseudoElement(items),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, Node> NonReplacedContents<Node>
|
impl NonReplacedContents {
|
||||||
where
|
pub(crate) fn traverse<'dom, Node>(
|
||||||
|
self,
|
||||||
|
context: &LayoutContext,
|
||||||
|
node: Node,
|
||||||
|
inherited_style: &ServoArc<ComputedValues>,
|
||||||
|
handler: &mut impl TraversalHandler<'dom, Node>,
|
||||||
|
) where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
pub(crate) fn traverse(
|
|
||||||
self,
|
|
||||||
inherited_style: &ServoArc<ComputedValues>,
|
|
||||||
context: &LayoutContext,
|
|
||||||
handler: &mut impl TraversalHandler<'dom, Node>,
|
|
||||||
) {
|
|
||||||
match self {
|
match self {
|
||||||
NonReplacedContents::OfElement(node) => traverse_children_of(node, context, handler),
|
NonReplacedContents::OfElement => traverse_children_of(node, context, handler),
|
||||||
NonReplacedContents::OfPseudoElement(items) => {
|
NonReplacedContents::OfPseudoElement(items) => {
|
||||||
traverse_pseudo_element_contents(inherited_style, context, handler, items)
|
traverse_pseudo_element_contents(node, inherited_style, context, handler, items)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,13 @@ use style::selector_parser::PseudoElement;
|
||||||
impl BlockFormattingContext {
|
impl BlockFormattingContext {
|
||||||
pub fn construct<'dom>(
|
pub fn construct<'dom>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
|
node: impl NodeExt<'dom>,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
contents: NonReplacedContents,
|
||||||
content_sizes: ContentSizesRequest,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> (Self, BoxContentSizes) {
|
) -> (Self, BoxContentSizes) {
|
||||||
let (contents, contains_floats, inline_content_sizes) =
|
let (contents, contains_floats, inline_content_sizes) =
|
||||||
BlockContainer::construct(context, style, contents, content_sizes);
|
BlockContainer::construct(context, node, style, contents, content_sizes);
|
||||||
// FIXME: add contribution to `inline_content_sizes` of floats in this formatting context
|
// FIXME: add contribution to `inline_content_sizes` of floats in this formatting context
|
||||||
// https://dbaron.org/css/intrinsic/#intrinsic
|
// https://dbaron.org/css/intrinsic/#intrinsic
|
||||||
let bfc = Self {
|
let bfc = Self {
|
||||||
|
@ -39,24 +40,25 @@ impl BlockFormattingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BlockLevelJob<'dom, Node> {
|
struct BlockLevelJob<'dom, Node> {
|
||||||
|
node: Node,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
kind: BlockLevelCreator<Node>,
|
kind: BlockLevelCreator,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BlockLevelCreator<Node> {
|
enum BlockLevelCreator {
|
||||||
SameFormattingContextBlock(IntermediateBlockContainer<Node>),
|
SameFormattingContextBlock(IntermediateBlockContainer),
|
||||||
Independent {
|
Independent {
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
},
|
},
|
||||||
OutOfFlowAbsolutelyPositionedBox {
|
OutOfFlowAbsolutelyPositionedBox {
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
},
|
},
|
||||||
OutOfFlowFloatBox {
|
OutOfFlowFloatBox {
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +69,9 @@ enum BlockLevelCreator<Node> {
|
||||||
/// of a given element.
|
/// of a given element.
|
||||||
///
|
///
|
||||||
/// Deferring allows using rayon’s `into_par_iter`.
|
/// Deferring allows using rayon’s `into_par_iter`.
|
||||||
enum IntermediateBlockContainer<Node> {
|
enum IntermediateBlockContainer {
|
||||||
InlineFormattingContext(InlineFormattingContext),
|
InlineFormattingContext(InlineFormattingContext),
|
||||||
Deferred(NonReplacedContents<Node>),
|
Deferred(NonReplacedContents),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A builder for a block container.
|
/// A builder for a block container.
|
||||||
|
@ -79,6 +81,8 @@ enum IntermediateBlockContainer<Node> {
|
||||||
struct BlockContainerBuilder<'dom, 'style, Node> {
|
struct BlockContainerBuilder<'dom, 'style, Node> {
|
||||||
context: &'style LayoutContext<'style>,
|
context: &'style LayoutContext<'style>,
|
||||||
|
|
||||||
|
root: Node,
|
||||||
|
|
||||||
block_container_style: &'style Arc<ComputedValues>,
|
block_container_style: &'style Arc<ComputedValues>,
|
||||||
|
|
||||||
/// The list of block-level boxes to be built for the final block container.
|
/// The list of block-level boxes to be built for the final block container.
|
||||||
|
@ -131,12 +135,14 @@ struct BlockContainerBuilder<'dom, 'style, Node> {
|
||||||
impl BlockContainer {
|
impl BlockContainer {
|
||||||
pub fn construct<'dom>(
|
pub fn construct<'dom>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
|
root: impl NodeExt<'dom>,
|
||||||
block_container_style: &Arc<ComputedValues>,
|
block_container_style: &Arc<ComputedValues>,
|
||||||
contents: NonReplacedContents<impl NodeExt<'dom>>,
|
contents: NonReplacedContents,
|
||||||
content_sizes: ContentSizesRequest,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> (BlockContainer, ContainsFloats, BoxContentSizes) {
|
) -> (BlockContainer, ContainsFloats, BoxContentSizes) {
|
||||||
let mut builder = BlockContainerBuilder {
|
let mut builder = BlockContainerBuilder {
|
||||||
context,
|
context,
|
||||||
|
root,
|
||||||
block_container_style,
|
block_container_style,
|
||||||
block_level_boxes: Vec::new(),
|
block_level_boxes: Vec::new(),
|
||||||
ongoing_inline_formatting_context: InlineFormattingContext::default(),
|
ongoing_inline_formatting_context: InlineFormattingContext::default(),
|
||||||
|
@ -145,7 +151,7 @@ impl BlockContainer {
|
||||||
contains_floats: ContainsFloats::No,
|
contains_floats: ContainsFloats::No,
|
||||||
};
|
};
|
||||||
|
|
||||||
contents.traverse(block_container_style, context, &mut builder);
|
contents.traverse(context, root, block_container_style, &mut builder);
|
||||||
|
|
||||||
debug_assert!(builder.ongoing_inline_boxes_stack.is_empty());
|
debug_assert!(builder.ongoing_inline_boxes_stack.is_empty());
|
||||||
|
|
||||||
|
@ -228,15 +234,16 @@ where
|
||||||
{
|
{
|
||||||
fn handle_element(
|
fn handle_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
node: Node,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
display: DisplayGeneratingBox,
|
display: DisplayGeneratingBox,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
) {
|
) {
|
||||||
match display {
|
match display {
|
||||||
DisplayGeneratingBox::OutsideInside { outside, inside } => match outside {
|
DisplayGeneratingBox::OutsideInside { outside, inside } => match outside {
|
||||||
DisplayOutside::Inline => box_slot.set(LayoutBox::InlineLevel(
|
DisplayOutside::Inline => box_slot.set(LayoutBox::InlineLevel(
|
||||||
self.handle_inline_level_element(style, inside, contents),
|
self.handle_inline_level_element(node, style, inside, contents),
|
||||||
)),
|
)),
|
||||||
DisplayOutside::Block => {
|
DisplayOutside::Block => {
|
||||||
let box_style = style.get_box();
|
let box_style = style.get_box();
|
||||||
|
@ -244,15 +251,22 @@ where
|
||||||
// https://drafts.csswg.org/css2/visuren.html#dis-pos-flo
|
// https://drafts.csswg.org/css2/visuren.html#dis-pos-flo
|
||||||
if box_style.position.is_absolutely_positioned() {
|
if box_style.position.is_absolutely_positioned() {
|
||||||
self.handle_absolutely_positioned_element(
|
self.handle_absolutely_positioned_element(
|
||||||
|
node,
|
||||||
style.clone(),
|
style.clone(),
|
||||||
inside,
|
inside,
|
||||||
contents,
|
contents,
|
||||||
box_slot,
|
box_slot,
|
||||||
)
|
)
|
||||||
} else if box_style.float.is_floating() {
|
} else if box_style.float.is_floating() {
|
||||||
self.handle_float_element(style.clone(), inside, contents, box_slot)
|
self.handle_float_element(node, style.clone(), inside, contents, box_slot)
|
||||||
} else {
|
} else {
|
||||||
self.handle_block_level_element(style.clone(), inside, contents, box_slot)
|
self.handle_block_level_element(
|
||||||
|
node,
|
||||||
|
style.clone(),
|
||||||
|
inside,
|
||||||
|
contents,
|
||||||
|
box_slot,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -365,9 +379,10 @@ where
|
||||||
|
|
||||||
fn handle_inline_level_element(
|
fn handle_inline_level_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
node: Node,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
) -> Arc<InlineLevelBox> {
|
) -> Arc<InlineLevelBox> {
|
||||||
let box_ = if display_inside == DisplayInside::Flow && !contents.is_replaced() {
|
let box_ = if display_inside == DisplayInside::Flow && !contents.is_replaced() {
|
||||||
// We found un inline box.
|
// We found un inline box.
|
||||||
|
@ -381,9 +396,12 @@ where
|
||||||
});
|
});
|
||||||
|
|
||||||
// `unwrap` doesn’t panic here because `is_replaced` returned `false`.
|
// `unwrap` doesn’t panic here because `is_replaced` returned `false`.
|
||||||
NonReplacedContents::try_from(contents)
|
NonReplacedContents::try_from(contents).unwrap().traverse(
|
||||||
.unwrap()
|
self.context,
|
||||||
.traverse(&style, self.context, self);
|
node,
|
||||||
|
&style,
|
||||||
|
self,
|
||||||
|
);
|
||||||
|
|
||||||
let mut inline_box = self
|
let mut inline_box = self
|
||||||
.ongoing_inline_boxes_stack
|
.ongoing_inline_boxes_stack
|
||||||
|
@ -395,6 +413,7 @@ where
|
||||||
Arc::new(InlineLevelBox::Atomic(
|
Arc::new(InlineLevelBox::Atomic(
|
||||||
IndependentFormattingContext::construct(
|
IndependentFormattingContext::construct(
|
||||||
self.context,
|
self.context,
|
||||||
|
node,
|
||||||
style.clone(),
|
style.clone(),
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
@ -408,9 +427,10 @@ where
|
||||||
|
|
||||||
fn handle_block_level_element(
|
fn handle_block_level_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
node: Node,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
) {
|
) {
|
||||||
// We just found a block level element, all ongoing inline level boxes
|
// We just found a block level element, all ongoing inline level boxes
|
||||||
|
@ -475,6 +495,7 @@ where
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
self.block_level_boxes.push(BlockLevelJob {
|
self.block_level_boxes.push(BlockLevelJob {
|
||||||
|
node,
|
||||||
box_slot,
|
box_slot,
|
||||||
style,
|
style,
|
||||||
kind,
|
kind,
|
||||||
|
@ -483,9 +504,10 @@ where
|
||||||
|
|
||||||
fn handle_absolutely_positioned_element(
|
fn handle_absolutely_positioned_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
node: Node,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
) {
|
) {
|
||||||
if !self.has_ongoing_inline_formatting_context() {
|
if !self.has_ongoing_inline_formatting_context() {
|
||||||
|
@ -494,13 +516,20 @@ where
|
||||||
display_inside,
|
display_inside,
|
||||||
};
|
};
|
||||||
self.block_level_boxes.push(BlockLevelJob {
|
self.block_level_boxes.push(BlockLevelJob {
|
||||||
|
node,
|
||||||
box_slot,
|
box_slot,
|
||||||
style,
|
style,
|
||||||
kind,
|
kind,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let box_ = Arc::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
let box_ = Arc::new(InlineLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
||||||
AbsolutelyPositionedBox::construct(self.context, style, display_inside, contents),
|
AbsolutelyPositionedBox::construct(
|
||||||
|
self.context,
|
||||||
|
node,
|
||||||
|
style,
|
||||||
|
display_inside,
|
||||||
|
contents,
|
||||||
|
),
|
||||||
));
|
));
|
||||||
self.current_inline_level_boxes().push(box_.clone());
|
self.current_inline_level_boxes().push(box_.clone());
|
||||||
box_slot.set(LayoutBox::InlineLevel(box_))
|
box_slot.set(LayoutBox::InlineLevel(box_))
|
||||||
|
@ -509,9 +538,10 @@ where
|
||||||
|
|
||||||
fn handle_float_element(
|
fn handle_float_element(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
node: Node,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<Node>,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
) {
|
) {
|
||||||
self.contains_floats = ContainsFloats::Yes;
|
self.contains_floats = ContainsFloats::Yes;
|
||||||
|
@ -522,6 +552,7 @@ where
|
||||||
display_inside,
|
display_inside,
|
||||||
};
|
};
|
||||||
self.block_level_boxes.push(BlockLevelJob {
|
self.block_level_boxes.push(BlockLevelJob {
|
||||||
|
node,
|
||||||
box_slot,
|
box_slot,
|
||||||
style,
|
style,
|
||||||
kind,
|
kind,
|
||||||
|
@ -529,6 +560,7 @@ where
|
||||||
} else {
|
} else {
|
||||||
let box_ = Arc::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox::construct(
|
let box_ = Arc::new(InlineLevelBox::OutOfFlowFloatBox(FloatBox::construct(
|
||||||
self.context,
|
self.context,
|
||||||
|
node,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
@ -567,6 +599,7 @@ where
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
self.block_level_boxes.push(BlockLevelJob {
|
self.block_level_boxes.push(BlockLevelJob {
|
||||||
|
node: self.root,
|
||||||
// FIXME(nox): We should be storing this somewhere.
|
// FIXME(nox): We should be storing this somewhere.
|
||||||
box_slot: BoxSlot::dummy(),
|
box_slot: BoxSlot::dummy(),
|
||||||
style: anonymous_style.clone(),
|
style: anonymous_style.clone(),
|
||||||
|
@ -599,11 +632,13 @@ where
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
|
max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
|
||||||
) -> (Arc<BlockLevelBox>, ContainsFloats) {
|
) -> (Arc<BlockLevelBox>, ContainsFloats) {
|
||||||
|
let node = self.node;
|
||||||
let style = self.style;
|
let style = self.style;
|
||||||
let (block_level_box, contains_floats) = match self.kind {
|
let (block_level_box, contains_floats) = match self.kind {
|
||||||
BlockLevelCreator::SameFormattingContextBlock(contents) => {
|
BlockLevelCreator::SameFormattingContextBlock(contents) => {
|
||||||
let (contents, contains_floats, box_content_sizes) = contents.finish(
|
let (contents, contains_floats, box_content_sizes) = contents.finish(
|
||||||
context,
|
context,
|
||||||
|
node,
|
||||||
&style,
|
&style,
|
||||||
ContentSizesRequest::inline_if(
|
ContentSizesRequest::inline_if(
|
||||||
max_assign_in_flow_outer_content_sizes_to.is_some() &&
|
max_assign_in_flow_outer_content_sizes_to.is_some() &&
|
||||||
|
@ -627,6 +662,7 @@ where
|
||||||
);
|
);
|
||||||
let contents = IndependentFormattingContext::construct(
|
let contents = IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
|
node,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
@ -645,7 +681,13 @@ where
|
||||||
contents,
|
contents,
|
||||||
} => {
|
} => {
|
||||||
let block_level_box = Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
let block_level_box = Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
||||||
AbsolutelyPositionedBox::construct(context, style, display_inside, contents),
|
AbsolutelyPositionedBox::construct(
|
||||||
|
context,
|
||||||
|
node,
|
||||||
|
style,
|
||||||
|
display_inside,
|
||||||
|
contents,
|
||||||
|
),
|
||||||
));
|
));
|
||||||
(block_level_box, ContainsFloats::No)
|
(block_level_box, ContainsFloats::No)
|
||||||
},
|
},
|
||||||
|
@ -654,7 +696,7 @@ where
|
||||||
contents,
|
contents,
|
||||||
} => {
|
} => {
|
||||||
let block_level_box = Arc::new(BlockLevelBox::OutOfFlowFloatBox(
|
let block_level_box = Arc::new(BlockLevelBox::OutOfFlowFloatBox(
|
||||||
FloatBox::construct(context, style, display_inside, contents),
|
FloatBox::construct(context, node, style, display_inside, contents),
|
||||||
));
|
));
|
||||||
(block_level_box, ContainsFloats::Yes)
|
(block_level_box, ContainsFloats::Yes)
|
||||||
},
|
},
|
||||||
|
@ -665,19 +707,17 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'dom, Node> IntermediateBlockContainer<Node>
|
impl IntermediateBlockContainer {
|
||||||
where
|
fn finish<'dom>(
|
||||||
Node: NodeExt<'dom>,
|
|
||||||
{
|
|
||||||
fn finish(
|
|
||||||
self,
|
self,
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
|
node: impl NodeExt<'dom>,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
content_sizes: ContentSizesRequest,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> (BlockContainer, ContainsFloats, BoxContentSizes) {
|
) -> (BlockContainer, ContainsFloats, BoxContentSizes) {
|
||||||
match self {
|
match self {
|
||||||
IntermediateBlockContainer::Deferred(contents) => {
|
IntermediateBlockContainer::Deferred(contents) => {
|
||||||
BlockContainer::construct(context, style, contents, content_sizes)
|
BlockContainer::construct(context, node, style, contents, content_sizes)
|
||||||
},
|
},
|
||||||
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
|
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
|
||||||
let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context));
|
let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context));
|
||||||
|
|
|
@ -29,14 +29,16 @@ impl FloatContext {
|
||||||
impl FloatBox {
|
impl FloatBox {
|
||||||
pub fn construct<'dom>(
|
pub fn construct<'dom>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
|
node: impl NodeExt<'dom>,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<impl NodeExt<'dom>>,
|
contents: Contents,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let content_sizes = ContentSizesRequest::inline_if(!style.inline_size_is_length());
|
let content_sizes = ContentSizesRequest::inline_if(!style.inline_size_is_length());
|
||||||
Self {
|
Self {
|
||||||
contents: IndependentFormattingContext::construct(
|
contents: IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
|
node,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
|
|
@ -61,19 +61,19 @@ fn construct_for_root_element<'dom>(
|
||||||
Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside,
|
Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside,
|
||||||
};
|
};
|
||||||
|
|
||||||
let contents = replaced.map_or(Contents::OfElement(root_element), Contents::Replaced);
|
let contents = replaced.map_or(Contents::OfElement, Contents::Replaced);
|
||||||
if box_style.position.is_absolutely_positioned() {
|
if box_style.position.is_absolutely_positioned() {
|
||||||
(
|
(
|
||||||
ContainsFloats::No,
|
ContainsFloats::No,
|
||||||
vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
vec![Arc::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
||||||
AbsolutelyPositionedBox::construct(context, style, display_inside, contents),
|
AbsolutelyPositionedBox::construct(context, root_element, style, display_inside, contents),
|
||||||
))],
|
))],
|
||||||
)
|
)
|
||||||
} else if box_style.float.is_floating() {
|
} else if box_style.float.is_floating() {
|
||||||
(
|
(
|
||||||
ContainsFloats::Yes,
|
ContainsFloats::Yes,
|
||||||
vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(
|
vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(
|
||||||
FloatBox::construct(context, style, display_inside, contents),
|
FloatBox::construct(context, root_element, style, display_inside, contents),
|
||||||
))],
|
))],
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,6 +82,7 @@ fn construct_for_root_element<'dom>(
|
||||||
vec![Arc::new(BlockLevelBox::Independent(
|
vec![Arc::new(BlockLevelBox::Independent(
|
||||||
IndependentFormattingContext::construct(
|
IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
|
root_element,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
|
|
@ -54,9 +54,10 @@ enum NonReplacedIFCKind<'a> {
|
||||||
impl IndependentFormattingContext {
|
impl IndependentFormattingContext {
|
||||||
pub fn construct<'dom>(
|
pub fn construct<'dom>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
|
node: impl NodeExt<'dom>,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<impl NodeExt<'dom>>,
|
contents: Contents,
|
||||||
content_sizes: ContentSizesRequest,
|
content_sizes: ContentSizesRequest,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
match contents.try_into() {
|
match contents.try_into() {
|
||||||
|
@ -64,6 +65,7 @@ impl IndependentFormattingContext {
|
||||||
DisplayInside::Flow | DisplayInside::FlowRoot => {
|
DisplayInside::Flow | DisplayInside::FlowRoot => {
|
||||||
let (bfc, content_sizes) = BlockFormattingContext::construct(
|
let (bfc, content_sizes) = BlockFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
|
node,
|
||||||
&style,
|
&style,
|
||||||
non_replaced,
|
non_replaced,
|
||||||
content_sizes,
|
content_sizes,
|
||||||
|
|
|
@ -60,9 +60,10 @@ pub(crate) enum AbsoluteBoxOffsets {
|
||||||
impl AbsolutelyPositionedBox {
|
impl AbsolutelyPositionedBox {
|
||||||
pub fn construct<'dom>(
|
pub fn construct<'dom>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
|
node: impl NodeExt<'dom>,
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
display_inside: DisplayInside,
|
display_inside: DisplayInside,
|
||||||
contents: Contents<impl NodeExt<'dom>>,
|
contents: Contents,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
|
// "Shrink-to-fit" in https://drafts.csswg.org/css2/visudet.html#abs-non-replaced-width
|
||||||
let content_sizes = ContentSizesRequest::inline_if(
|
let content_sizes = ContentSizesRequest::inline_if(
|
||||||
|
@ -76,6 +77,7 @@ impl AbsolutelyPositionedBox {
|
||||||
Self {
|
Self {
|
||||||
contents: IndependentFormattingContext::construct(
|
contents: IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
|
node,
|
||||||
style,
|
style,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue