Auto merge of #24243 - servo:box-construct, r=SimonSapin

Uncomment more stuff related to box construction

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/24243)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2019-09-23 17:00:25 -04:00 committed by GitHub
commit ee17eedf3a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 323 additions and 278 deletions

View file

@ -6,13 +6,15 @@ use crate::element_data::{LayoutBox, LayoutDataForElement};
use crate::replaced::ReplacedContent; use crate::replaced::ReplacedContent;
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside, DisplayOutside}; use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside, DisplayOutside};
use crate::wrapper::GetRawData; use crate::wrapper::GetRawData;
use atomic_refcell::AtomicRefMut; use atomic_refcell::{AtomicRefCell, AtomicRefMut};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode}; use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use servo_arc::Arc; use servo_arc::Arc;
use std::convert::TryInto; use std::convert::TryInto;
use std::marker::PhantomData as marker;
use style::context::SharedStyleContext; use style::context::SharedStyleContext;
use style::dom::TNode; use style::dom::TNode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub(super) enum WhichPseudoElement { pub(super) enum WhichPseudoElement {
@ -43,7 +45,10 @@ pub(super) enum PseudoElementContentItem {
Replaced(ReplacedContent), Replaced(ReplacedContent),
} }
pub(super) trait TraversalHandler<Node> { pub(super) trait TraversalHandler<'dom, Node>
where
Node: 'dom,
{
fn handle_text(&mut self, text: String, parent_style: &Arc<ComputedValues>); fn handle_text(&mut self, text: String, parent_style: &Arc<ComputedValues>);
/// Or pseudo-element /// Or pseudo-element
@ -52,14 +57,14 @@ pub(super) trait TraversalHandler<Node> {
style: &Arc<ComputedValues>, style: &Arc<ComputedValues>,
display: DisplayGeneratingBox, display: DisplayGeneratingBox,
contents: Contents<Node>, contents: Contents<Node>,
box_slot: BoxSlot, box_slot: BoxSlot<'dom>,
); );
} }
fn traverse_children_of<'dom, Node>( fn traverse_children_of<'dom, Node>(
parent_element: Node, parent_element: Node,
context: &SharedStyleContext, context: &SharedStyleContext,
handler: &mut impl TraversalHandler<Node>, handler: &mut impl TraversalHandler<'dom, Node>,
) where ) where
Node: NodeExt<'dom>, Node: NodeExt<'dom>,
{ {
@ -81,7 +86,7 @@ fn traverse_children_of<'dom, Node>(
fn traverse_element<'dom, Node>( fn traverse_element<'dom, Node>(
element: Node, element: Node,
context: &SharedStyleContext, context: &SharedStyleContext,
handler: &mut impl TraversalHandler<Node>, handler: &mut impl TraversalHandler<'dom, Node>,
) where ) where
Node: NodeExt<'dom>, Node: NodeExt<'dom>,
{ {
@ -94,7 +99,7 @@ fn traverse_element<'dom, Node>(
// <https://drafts.csswg.org/css-display-3/#valdef-display-contents> // <https://drafts.csswg.org/css-display-3/#valdef-display-contents>
element.unset_boxes_in_subtree() element.unset_boxes_in_subtree()
} else { } else {
element.layout_data_mut().self_box = Some(LayoutBox::DisplayContents); *element.layout_data_mut().self_box.borrow_mut() = Some(LayoutBox::DisplayContents);
traverse_children_of(element, context, handler) traverse_children_of(element, context, handler)
} }
}, },
@ -116,7 +121,7 @@ fn traverse_pseudo_element<'dom, Node>(
which: WhichPseudoElement, which: WhichPseudoElement,
element: Node, element: Node,
context: &SharedStyleContext, context: &SharedStyleContext,
handler: &mut impl TraversalHandler<Node>, handler: &mut impl TraversalHandler<'dom, Node>,
) where ) where
Node: NodeExt<'dom>, Node: NodeExt<'dom>,
{ {
@ -126,7 +131,7 @@ 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, items, handler); traverse_pseudo_element_contents(&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);
@ -140,33 +145,42 @@ fn traverse_pseudo_element<'dom, Node>(
fn traverse_pseudo_element_contents<'dom, Node>( fn traverse_pseudo_element_contents<'dom, Node>(
pseudo_element_style: &Arc<ComputedValues>, pseudo_element_style: &Arc<ComputedValues>,
context: &SharedStyleContext,
handler: &mut impl TraversalHandler<'dom, Node>,
items: Vec<PseudoElementContentItem>, items: Vec<PseudoElementContentItem>,
handler: &mut impl TraversalHandler<Node>,
) where ) where
Node: 'dom, Node: NodeExt<'dom>,
{ {
// let mut anonymous_style = None; let mut anonymous_style = None;
for item in items { for item in items {
match item { match item {
PseudoElementContentItem::Text(text) => handler.handle_text(text, pseudo_element_style), PseudoElementContentItem::Text(text) => handler.handle_text(text, pseudo_element_style),
PseudoElementContentItem::Replaced(contents) => { PseudoElementContentItem::Replaced(contents) => {
// FIXME let item_style = anonymous_style.get_or_insert_with(|| {
// let item_style = anonymous_style.get_or_insert_with(|| { context
// ComputedValues::anonymous_inheriting_from(Some(pseudo_element_style)) .stylist
// }); .style_for_anonymous::<Node::ConcreteElement>(
// let display_inline = DisplayGeneratingBox::OutsideInside { &context.guards,
// outside: DisplayOutside::Inline, &PseudoElement::ServoText,
// inside: DisplayInside::Flow, &pseudo_element_style,
// }; )
// // `display` is not inherited, so we get the initial value });
// debug_assert!(item_style.box_.display == Display::GeneratingBox(display_inline)); let display_inline = DisplayGeneratingBox::OutsideInside {
// handler.handle_element( outside: DisplayOutside::Inline,
// item_style, inside: DisplayInside::Flow,
// display_inline, };
// Contents::Replaced(contents), // `display` is not inherited, so we get the initial value
// // We dont keep pointers to boxes generated by contents of pseudo-elements debug_assert!(
// BoxSlot::dummy(), Display::from(item_style.get_box().display) ==
// ) Display::GeneratingBox(display_inline)
);
handler.handle_element(
item_style,
display_inline,
Contents::Replaced(contents),
// We dont keep pointers to boxes generated by contents of pseudo-elements
BoxSlot::dummy(),
)
}, },
} }
} }
@ -201,12 +215,12 @@ where
self, self,
inherited_style: &Arc<ComputedValues>, inherited_style: &Arc<ComputedValues>,
context: &SharedStyleContext, context: &SharedStyleContext,
handler: &mut impl TraversalHandler<Node>, handler: &mut impl TraversalHandler<'dom, Node>,
) { ) {
match self { match self {
NonReplacedContents::OfElement(node) => traverse_children_of(node, context, handler), NonReplacedContents::OfElement(node) => traverse_children_of(node, context, handler),
NonReplacedContents::OfPseudoElement(items) => { NonReplacedContents::OfPseudoElement(items) => {
traverse_pseudo_element_contents(inherited_style, items, handler) traverse_pseudo_element_contents(inherited_style, context, handler, items)
}, },
} }
} }
@ -239,22 +253,25 @@ where
} }
pub(super) struct BoxSlot<'dom> { pub(super) struct BoxSlot<'dom> {
slot: Option<AtomicRefMut<'dom, Option<LayoutBox>>>, slot: Option<Arc<AtomicRefCell<Option<LayoutBox>>>>,
marker: marker<&'dom ()>,
} }
impl<'dom> BoxSlot<'dom> { impl BoxSlot<'_> {
pub fn new(mut slot: AtomicRefMut<'dom, Option<LayoutBox>>) -> Self { pub fn new(slot: Arc<AtomicRefCell<Option<LayoutBox>>>) -> Self {
*slot = None; *slot.borrow_mut() = None;
Self { slot: Some(slot) } let slot = Some(slot);
Self { slot, marker }
} }
pub fn dummy() -> Self { pub fn dummy() -> Self {
Self { slot: None } let slot = None;
Self { slot, marker }
} }
pub fn set(mut self, box_: LayoutBox) { pub fn set(mut self, box_: LayoutBox) {
if let Some(slot) = &mut self.slot { if let Some(slot) = &mut self.slot {
**slot = Some(box_) *slot.borrow_mut() = Some(box_);
} }
} }
} }
@ -262,12 +279,12 @@ impl<'dom> BoxSlot<'dom> {
impl Drop for BoxSlot<'_> { impl Drop for BoxSlot<'_> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(slot) = &mut self.slot { if let Some(slot) = &mut self.slot {
assert!(slot.is_some(), "failed to set a layout box") assert!(slot.borrow().is_some(), "failed to set a layout box");
} }
} }
} }
pub(crate) trait NodeExt<'dom>: 'dom + Copy + Send + Sync { pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode + Send + Sync {
fn is_element(self) -> bool; fn is_element(self) -> bool;
fn as_text(self) -> Option<String>; fn as_text(self) -> Option<String>;
fn first_child(self) -> Option<Self>; fn first_child(self) -> Option<Self>;
@ -276,15 +293,15 @@ pub(crate) trait NodeExt<'dom>: 'dom + Copy + Send + Sync {
fn style(self, context: &SharedStyleContext) -> Arc<ComputedValues>; fn style(self, context: &SharedStyleContext) -> Arc<ComputedValues>;
fn layout_data_mut(&self) -> AtomicRefMut<LayoutDataForElement>; fn layout_data_mut(&self) -> AtomicRefMut<LayoutDataForElement>;
fn element_box_slot(&self) -> BoxSlot; fn element_box_slot(&self) -> BoxSlot<'dom>;
fn pseudo_element_box_slot(&self, which: WhichPseudoElement) -> BoxSlot; fn pseudo_element_box_slot(&self, which: WhichPseudoElement) -> BoxSlot<'dom>;
fn unset_pseudo_element_box(self, which: WhichPseudoElement); fn unset_pseudo_element_box(self, which: WhichPseudoElement);
fn unset_boxes_in_subtree(self); fn unset_boxes_in_subtree(self);
} }
impl<'dom, T> NodeExt<'dom> for T impl<'dom, T> NodeExt<'dom> for T
where where
T: 'dom + LayoutNode + Send + Sync, T: 'dom + Copy + LayoutNode + Send + Sync,
{ {
fn is_element(self) -> bool { fn is_element(self) -> bool {
self.to_threadsafe().as_element().is_some() self.to_threadsafe().as_element().is_some()
@ -320,27 +337,25 @@ where
.unwrap() .unwrap()
} }
fn element_box_slot(&self) -> BoxSlot { fn element_box_slot(&self) -> BoxSlot<'dom> {
BoxSlot::new(AtomicRefMut::map(self.layout_data_mut(), |data| { BoxSlot::new(self.layout_data_mut().self_box.clone())
&mut data.self_box
}))
} }
fn pseudo_element_box_slot(&self, which: WhichPseudoElement) -> BoxSlot { fn pseudo_element_box_slot(&self, which: WhichPseudoElement) -> BoxSlot<'dom> {
BoxSlot::new(AtomicRefMut::map(self.layout_data_mut(), |data| { let mut data = self.layout_data_mut();
let pseudos = data.pseudo_elements.get_or_insert_with(Default::default); let pseudos = data.pseudo_elements.get_or_insert_with(Default::default);
match which { let cell = match which {
WhichPseudoElement::Before => &mut pseudos.before, WhichPseudoElement::Before => &mut pseudos.before,
WhichPseudoElement::After => &mut pseudos.after, WhichPseudoElement::After => &mut pseudos.after,
} };
})) BoxSlot::new(cell.clone())
} }
fn unset_pseudo_element_box(self, which: WhichPseudoElement) { fn unset_pseudo_element_box(self, which: WhichPseudoElement) {
if let Some(pseudos) = &mut self.layout_data_mut().pseudo_elements { if let Some(pseudos) = &mut self.layout_data_mut().pseudo_elements {
match which { match which {
WhichPseudoElement::Before => pseudos.before = None, WhichPseudoElement::Before => *pseudos.before.borrow_mut() = None,
WhichPseudoElement::After => pseudos.after = None, WhichPseudoElement::After => *pseudos.after.borrow_mut() = None,
} }
} }
} }
@ -352,7 +367,8 @@ where
let traverse_children = { let traverse_children = {
let mut layout_data = node.layout_data_mut(); let mut layout_data = node.layout_data_mut();
layout_data.pseudo_elements = None; layout_data.pseudo_elements = None;
layout_data.self_box.take().is_some() let self_box = layout_data.self_box.borrow_mut().take();
self_box.is_some()
}; };
if traverse_children { if traverse_children {
// Only descend into children if we removed a box. // Only descend into children if we removed a box.

View file

@ -4,18 +4,19 @@
use crate::flow::inline::InlineLevelBox; use crate::flow::inline::InlineLevelBox;
use crate::flow::BlockLevelBox; use crate::flow::BlockLevelBox;
use atomic_refcell::AtomicRefCell;
use servo_arc::Arc; use servo_arc::Arc;
#[derive(Default)] #[derive(Default)]
pub(crate) struct LayoutDataForElement { pub(crate) struct LayoutDataForElement {
pub(super) self_box: Option<LayoutBox>, pub(super) self_box: Arc<AtomicRefCell<Option<LayoutBox>>>,
pub(super) pseudo_elements: Option<Box<PseudoElementBoxes>>, pub(super) pseudo_elements: Option<Box<PseudoElementBoxes>>,
} }
#[derive(Default)] #[derive(Default)]
pub(super) struct PseudoElementBoxes { pub(super) struct PseudoElementBoxes {
pub before: Option<LayoutBox>, pub before: Arc<AtomicRefCell<Option<LayoutBox>>>,
pub after: Option<LayoutBox>, pub after: Arc<AtomicRefCell<Option<LayoutBox>>>,
} }
pub(super) enum LayoutBox { pub(super) enum LayoutBox {

View file

@ -9,13 +9,14 @@ use crate::flow::inline::{InlineBox, InlineFormattingContext, InlineLevelBox, Te
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox}; use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
use crate::positioned::AbsolutelyPositionedBox; use crate::positioned::AbsolutelyPositionedBox;
use crate::style_ext::{DisplayGeneratingBox, DisplayInside, DisplayOutside}; use crate::style_ext::{DisplayGeneratingBox, DisplayInside, DisplayOutside};
use crate::IndependentFormattingContext; use crate::{take, IndependentFormattingContext};
use rayon::iter::{IntoParallelIterator, ParallelIterator}; use rayon::iter::{IntoParallelIterator, ParallelIterator};
use rayon_croissant::ParallelIteratorExt; use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc; use servo_arc::Arc;
use std::convert::TryInto; use std::convert::TryInto;
use style::context::SharedStyleContext; use style::context::SharedStyleContext;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::PseudoElement;
impl BlockFormattingContext { impl BlockFormattingContext {
pub fn construct<'dom>( pub fn construct<'dom>(
@ -152,8 +153,7 @@ impl BlockContainer {
); );
return (container, builder.contains_floats); return (container, builder.contains_floats);
} }
// FIXME builder.end_ongoing_inline_formatting_context();
// builder.end_ongoing_inline_formatting_context();
} }
let mut contains_floats = builder.contains_floats; let mut contains_floats = builder.contains_floats;
@ -166,8 +166,7 @@ impl BlockContainer {
|contains_floats, (intermediate, box_slot): (IntermediateBlockLevelBox<_>, BoxSlot<'_>)| { |contains_floats, (intermediate, box_slot): (IntermediateBlockLevelBox<_>, BoxSlot<'_>)| {
let (block_level_box, box_contains_floats) = intermediate.finish(context); let (block_level_box, box_contains_floats) = intermediate.finish(context);
*contains_floats |= box_contains_floats; *contains_floats |= box_contains_floats;
// FIXME box_slot.set(LayoutBox::BlockLevel(block_level_box.clone()));
// box_slot.set(LayoutBox::BlockLevel(block_level_box.clone()));
block_level_box block_level_box
}, },
|left, right| *left |= right, |left, right| *left |= right,
@ -178,7 +177,7 @@ impl BlockContainer {
} }
} }
impl<'dom, Node> TraversalHandler<Node> for BlockContainerBuilder<'dom, '_, Node> impl<'dom, Node> TraversalHandler<'dom, Node> for BlockContainerBuilder<'dom, '_, Node>
where where
Node: NodeExt<'dom>, Node: NodeExt<'dom>,
{ {
@ -187,7 +186,7 @@ where
style: &Arc<ComputedValues>, style: &Arc<ComputedValues>,
display: DisplayGeneratingBox, display: DisplayGeneratingBox,
contents: Contents<Node>, contents: Contents<Node>,
box_slot: BoxSlot, box_slot: BoxSlot<'dom>,
) { ) {
match display { match display {
DisplayGeneratingBox::OutsideInside { outside, inside } => match outside { DisplayGeneratingBox::OutsideInside { outside, inside } => match outside {
@ -195,21 +194,21 @@ where
self.handle_inline_level_element(style, inside, contents), self.handle_inline_level_element(style, inside, contents),
)), )),
DisplayOutside::Block => { DisplayOutside::Block => {
// FIXME let box_style = style.get_box();
// Floats and abspos cause blockification, so they only happen in this case. // Floats and abspos cause blockification, so they only happen in this case.
// https://drafts.csswg.org/css2/visuren.html#dis-pos-flo // https://drafts.csswg.org/css2/visuren.html#dis-pos-flo
// if style.box_.position.is_absolutely_positioned() { if box_style.position.is_absolutely_positioned() {
// self.handle_absolutely_positioned_element( self.handle_absolutely_positioned_element(
// style.clone(), style.clone(),
// inside, inside,
// contents, contents,
// box_slot, box_slot,
// ) )
// } else if style.box_.float.is_floating() { } else if box_style.float.is_floating() {
// self.handle_float_element(style.clone(), inside, contents, box_slot) self.handle_float_element(style.clone(), inside, contents, box_slot)
// } else { } else {
// self.handle_block_level_element(style.clone(), inside, contents, box_slot) self.handle_block_level_element(style.clone(), inside, contents, box_slot)
// } }
}, },
DisplayOutside::None => panic!(":("), DisplayOutside::None => panic!(":("),
}, },
@ -362,80 +361,79 @@ where
box_ box_
} }
// FIXME fn handle_block_level_element(
// fn handle_block_level_element( &mut self,
// &mut self, style: Arc<ComputedValues>,
// style: Arc<ComputedValues>, display_inside: DisplayInside,
// display_inside: DisplayInside, contents: Contents<Node>,
// contents: Contents, box_slot: BoxSlot<'dom>,
// box_slot: BoxSlot<'a>, ) {
// ) { // We just found a block level element, all ongoing inline level boxes
// // We just found a block level element, all ongoing inline level boxes // need to be split around it. We iterate on the fragmented inline
// // need to be split around it. We iterate on the fragmented inline // level box stack to take their contents and set their first_fragment
// // level box stack to take their contents and set their first_fragment // field to false, for the fragmented inline level boxes that will
// // field to false, for the fragmented inline level boxes that will // come after the block level element.
// // come after the block level element. let mut fragmented_inline_boxes =
// let mut fragmented_inline_boxes = self.ongoing_inline_boxes_stack
// self.ongoing_inline_boxes_stack .iter_mut()
// .iter_mut() .rev()
// .rev() .map(|ongoing| {
// .map(|ongoing| { let fragmented = InlineBox {
// let fragmented = InlineBox { style: ongoing.style.clone(),
// style: ongoing.style.clone(), first_fragment: ongoing.first_fragment,
// first_fragment: ongoing.first_fragment, // The fragmented boxes before the block level element
// // The fragmented boxes before the block level element // are obviously not the last fragment.
// // are obviously not the last fragment. last_fragment: false,
// last_fragment: false, children: take(&mut ongoing.children),
// children: take(&mut ongoing.children), };
// }; ongoing.first_fragment = false;
// ongoing.first_fragment = false; fragmented
// fragmented });
// });
// if let Some(last) = fragmented_inline_boxes.next() { if let Some(last) = fragmented_inline_boxes.next() {
// // There were indeed some ongoing inline level boxes before // There were indeed some ongoing inline level boxes before
// // the block, we accumulate them as a single inline level box // the block, we accumulate them as a single inline level box
// // to be pushed to the ongoing inline formatting context. // to be pushed to the ongoing inline formatting context.
// let mut fragmented_inline = InlineLevelBox::InlineBox(last); let mut fragmented_inline = InlineLevelBox::InlineBox(last);
// for mut fragmented_parent_inline_box in fragmented_inline_boxes { for mut fragmented_parent_inline_box in fragmented_inline_boxes {
// fragmented_parent_inline_box fragmented_parent_inline_box
// .children .children
// .push(Arc::new(fragmented_inline)); .push(Arc::new(fragmented_inline));
// fragmented_inline = InlineLevelBox::InlineBox(fragmented_parent_inline_box); fragmented_inline = InlineLevelBox::InlineBox(fragmented_parent_inline_box);
// } }
// self.ongoing_inline_formatting_context self.ongoing_inline_formatting_context
// .inline_level_boxes .inline_level_boxes
// .push(Arc::new(fragmented_inline)); .push(Arc::new(fragmented_inline));
// } }
// // We found a block level element, so the ongoing inline formatting // We found a block level element, so the ongoing inline formatting
// // context needs to be ended. // context needs to be ended.
// self.end_ongoing_inline_formatting_context(); self.end_ongoing_inline_formatting_context();
// let intermediate_box = match contents.try_into() { let intermediate_box = match contents.try_into() {
// Ok(contents) => match display_inside { Ok(contents) => match display_inside {
// DisplayInside::Flow => IntermediateBlockLevelBox::SameFormattingContextBlock { DisplayInside::Flow => IntermediateBlockLevelBox::SameFormattingContextBlock {
// style, style,
// contents: IntermediateBlockContainer::Deferred { contents }, contents: IntermediateBlockContainer::Deferred { contents },
// }, },
// _ => IntermediateBlockLevelBox::Independent { _ => IntermediateBlockLevelBox::Independent {
// style, style,
// display_inside, display_inside,
// contents: contents.into(), contents: contents.into(),
// }, },
// }, },
// Err(contents) => { Err(contents) => {
// let contents = Contents::Replaced(contents); let contents = Contents::Replaced(contents);
// IntermediateBlockLevelBox::Independent { IntermediateBlockLevelBox::Independent {
// style, style,
// display_inside, display_inside,
// contents, contents,
// } }
// } },
// }; };
// self.block_level_boxes.push((intermediate_box, box_slot)) self.block_level_boxes.push((intermediate_box, box_slot))
// } }
fn handle_absolutely_positioned_element( fn handle_absolutely_positioned_element(
&mut self, &mut self,
@ -514,22 +512,25 @@ where
return; return;
} }
let context = self.context;
let block_container_style = self.block_container_style; let block_container_style = self.block_container_style;
// FIXME let anonymous_style = self.anonymous_style.get_or_insert_with(|| {
// let anonymous_style = self.anonymous_style.get_or_insert_with(|| { context
// // If parent_style is None, the parent is the document node, .stylist
// // in which case anonymous inline boxes should inherit their .style_for_anonymous::<Node::ConcreteElement>(
// // styles from initial values. &context.guards,
// ComputedValues::anonymous_inheriting_from(Some(block_container_style)) &PseudoElement::ServoText,
// }); &block_container_style,
)
});
// let box_ = IntermediateBlockLevelBox::SameFormattingContextBlock { let box_ = IntermediateBlockLevelBox::SameFormattingContextBlock {
// style: anonymous_style.clone(), style: anonymous_style.clone(),
// contents: IntermediateBlockContainer::InlineFormattingContext(take( contents: IntermediateBlockContainer::InlineFormattingContext(take(
// &mut self.ongoing_inline_formatting_context, &mut self.ongoing_inline_formatting_context,
// )), )),
// }; };
// self.block_level_boxes.push((box_, BoxSlot::dummy())) self.block_level_boxes.push((box_, BoxSlot::dummy()))
} }
fn current_inline_level_boxes(&mut self) -> &mut Vec<Arc<InlineLevelBox>> { fn current_inline_level_boxes(&mut self) -> &mut Vec<Arc<InlineLevelBox>> {

View file

@ -2,7 +2,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use super::*; use crate::dom_traversal::{Contents, NodeExt};
use crate::flow::construct::ContainsFloats;
use crate::flow::float::FloatBox;
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
use crate::fragments::Fragment;
use crate::geom;
use crate::geom::flow_relative::Vec2;
use crate::positioned::AbsolutelyPositionedBox;
use crate::replaced::ReplacedContent;
use crate::style_ext::{
Direction, Display, DisplayGeneratingBox, DisplayInside, DisplayOutside, WritingMode,
};
use crate::{ContainingBlock, DefiniteContainingBlock, IndependentFormattingContext};
use rayon::iter::{IntoParallelRefIterator, ParallelExtend, ParallelIterator};
use servo_arc::Arc;
use style::context::SharedStyleContext;
use style::properties::ComputedValues;
use style::values::computed::{Length, LengthOrAuto};
use style_traits::CSSPixel;
// FIXME // FIXME
// impl crate::dom::Document { // impl crate::dom::Document {
@ -16,114 +34,107 @@ use super::*;
struct BoxTreeRoot(BlockFormattingContext); struct BoxTreeRoot(BlockFormattingContext);
// FIXME impl BoxTreeRoot {
// impl BoxTreeRoot { pub fn construct<'dom>(
// pub fn construct(document: &dom::Document) -> Self { context: &SharedStyleContext<'_>,
// let author_styles = &document.parse_stylesheets(); root_element: impl NodeExt<'dom>,
// let context = Context { ) -> Self {
// document, let (contains_floats, boxes) = construct_for_root_element(&context, root_element);
// author_styles, Self(BlockFormattingContext {
// }; contains_floats: contains_floats == ContainsFloats::Yes,
// let root_element = document.root_element(); contents: BlockContainer::BlockLevelBoxes(boxes),
// let style = style_for_element(context.author_styles, context.document, root_element, None); })
// let (contains_floats, boxes) = construct_for_root_element(&context, root_element, style); }
// Self(BlockFormattingContext { }
// contains_floats: contains_floats == ContainsFloats::Yes,
// contents: BlockContainer::BlockLevelBoxes(boxes),
// })
// }
// }
// fn construct_for_root_element( fn construct_for_root_element<'dom>(
// context: &Context, context: &SharedStyleContext<'_>,
// root_element: dom::NodeId, root_element: impl NodeExt<'dom>,
// style: Arc<ComputedValues>, ) -> (ContainsFloats, Vec<Arc<BlockLevelBox>>) {
// ) -> (ContainsFloats, Vec<Arc<BlockLevelBox>>) { let style = root_element.style(context);
// let replaced = ReplacedContent::for_element(root_element, context); let replaced = ReplacedContent::for_element(root_element, context);
let box_style = style.get_box();
// let display_inside = match style.box_.display { let display_inside = match Display::from(box_style.display) {
// Display::None => return (ContainsFloats::No, Vec::new()), Display::None => return (ContainsFloats::No, Vec::new()),
// Display::Contents if replaced.is_some() => { Display::Contents if replaced.is_some() => {
// // 'display: contents' computes to 'none' for replaced elements // 'display: contents' computes to 'none' for replaced elements
// return (ContainsFloats::No, Vec::new()); return (ContainsFloats::No, Vec::new());
// } },
// // https://drafts.csswg.org/css-display-3/#transformations // https://drafts.csswg.org/css-display-3/#transformations
// Display::Contents => DisplayInside::Flow, Display::Contents => DisplayInside::Flow,
// // The root element is blockified, ignore DisplayOutside // The root element is blockified, ignore DisplayOutside
// Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside, Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside,
// }; };
// if let Some(replaced) = replaced { if let Some(replaced) = replaced {
// let _box = match replaced {}; let _box = match replaced {};
// #[allow(unreachable_code)] #[allow(unreachable_code)]
// { {
// return (ContainsFloats::No, vec![Arc::new(_box)]); return (ContainsFloats::No, vec![Arc::new(_box)]);
// } }
// } }
// let contents = IndependentFormattingContext::construct( let contents = IndependentFormattingContext::construct(
// context, context,
// &style, &style,
// display_inside, display_inside,
// Contents::OfElement(root_element), Contents::OfElement(root_element),
// ); );
// if style.box_.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 { style, contents }, AbsolutelyPositionedBox { style, contents },
// ))], ))],
// ) )
// } else if style.box_.float.is_floating() { } else if box_style.float.is_floating() {
// ( (
// ContainsFloats::Yes, ContainsFloats::Yes,
// vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox { vec![Arc::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox {
// contents, contents,
// style, style,
// }))], }))],
// ) )
// } else { } else {
// ( (
// ContainsFloats::No, ContainsFloats::No,
// vec![Arc::new(BlockLevelBox::Independent { style, contents })], vec![Arc::new(BlockLevelBox::Independent { style, contents })],
// ) )
// } }
// } }
// impl BoxTreeRoot { impl BoxTreeRoot {
// fn layout(&self, viewport: crate::geom::Size<crate::geom::CssPx>) -> Vec<Fragment> { fn layout(&self, viewport: geom::Size<CSSPixel>) -> Vec<Fragment> {
// let initial_containing_block_size = Vec2 { let initial_containing_block_size = Vec2 {
// inline: Length { px: viewport.width }, inline: Length::new(viewport.width),
// block: Length { block: Length::new(viewport.height),
// px: viewport.height, };
// },
// };
// let initial_containing_block = ContainingBlock { let initial_containing_block = ContainingBlock {
// inline_size: initial_containing_block_size.inline, inline_size: initial_containing_block_size.inline,
// block_size: LengthOrAuto::Length(initial_containing_block_size.block), block_size: LengthOrAuto::LengthPercentage(initial_containing_block_size.block),
// // FIXME: use the documents mode: // FIXME: use the documents mode:
// // https://drafts.csswg.org/css-writing-modes/#principal-flow // https://drafts.csswg.org/css-writing-modes/#principal-flow
// mode: (WritingMode::HorizontalTb, Direction::Ltr), mode: (WritingMode::HorizontalTb, Direction::Ltr),
// }; };
// let dummy_tree_rank = 0; let dummy_tree_rank = 0;
// let mut absolutely_positioned_fragments = vec![]; let mut absolutely_positioned_fragments = vec![];
// let mut fragments = self.0.layout( let mut flow_children = self.0.layout(
// &initial_containing_block, &initial_containing_block,
// &mut absolutely_positioned_fragments, dummy_tree_rank,
// dummy_tree_rank, &mut absolutely_positioned_fragments,
// &mut PlacementState::root(), );
// );
// let initial_containing_block = DefiniteContainingBlock { let initial_containing_block = DefiniteContainingBlock {
// size: initial_containing_block_size, size: initial_containing_block_size,
// mode: initial_containing_block.mode, mode: initial_containing_block.mode,
// }; };
// fragments.par_extend( flow_children.fragments.par_extend(
// absolutely_positioned_fragments absolutely_positioned_fragments
// .par_iter() .par_iter()
// .map(|a| a.layout(&initial_containing_block)), .map(|a| a.layout(&initial_containing_block)),
// ); );
// fragments flow_children.fragments
// } }
// } }

View file

@ -42,15 +42,24 @@ ${helpers.single_keyword(
spec="Internal (not web-exposed)", spec="Internal (not web-exposed)",
)} )}
${helpers.single_keyword( <%helpers:single_keyword
"position", name="position"
"static absolute relative fixed" + (" sticky" if engine in ["gecko", "servo-2013"] else ""), values="static absolute relative fixed ${'sticky' if engine in ['gecko', 'servo-2013'] else ''}"
engines="gecko servo-2013 servo-2020", engines="gecko servo-2013 servo-2020"
animation_value_type="discrete", animation_value_type="discrete"
flags="CREATES_STACKING_CONTEXT ABSPOS_CB", flags="CREATES_STACKING_CONTEXT ABSPOS_CB"
spec="https://drafts.csswg.org/css-position/#position-property", spec="https://drafts.csswg.org/css-position/#position-property"
servo_restyle_damage="rebuild_and_reflow", servo_restyle_damage="rebuild_and_reflow"
)} >
impl computed_value::T {
pub fn is_absolutely_positioned(self) -> bool {
match self {
Self::Absolute | Self::Fixed => true,
_ => false,
}
}
}
</%helpers:single_keyword>
${helpers.predefined_type( ${helpers.predefined_type(
"float", "float",

View file

@ -61,6 +61,13 @@ pub enum Float {
None, None,
} }
impl Float {
/// Returns true if `self` is not `None`.
pub fn is_floating(self) -> bool {
self != Self::None
}
}
impl ToComputedValue for SpecifiedFloat { impl ToComputedValue for SpecifiedFloat {
type ComputedValue = Float; type ComputedValue = Float;