Add box construction for 'inline-block'…

… and other atomic inline-level boxes.
This commit is contained in:
Simon Sapin 2019-12-03 11:01:58 +01:00
parent 303b36f17b
commit da36fcddb0
2 changed files with 38 additions and 29 deletions

View file

@ -188,6 +188,17 @@ fn traverse_pseudo_element_contents<'dom, Node>(
} }
} }
impl<Node> Contents<Node> {
/// Returns true iff the `try_from` impl below would return `Err(_)`
pub fn is_replaced(&self) -> bool {
match self {
Contents::OfElement(_) |
Contents::OfPseudoElement(_) => false,
Contents::Replaced(_) => true,
}
}
}
impl<Node> std::convert::TryFrom<Contents<Node>> for NonReplacedContents<Node> { impl<Node> std::convert::TryFrom<Contents<Node>> for NonReplacedContents<Node> {
type Error = ReplacedContent; type Error = ReplacedContent;

View file

@ -15,7 +15,7 @@ use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, D
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::{TryFrom, TryInto};
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::PseudoElement; use style::selector_parser::PseudoElement;
@ -355,39 +355,37 @@ where
display_inside: DisplayInside, display_inside: DisplayInside,
contents: Contents<Node>, contents: Contents<Node>,
) -> Arc<InlineLevelBox> { ) -> Arc<InlineLevelBox> {
let box_ = match contents.try_into() { let box_ = if display_inside == DisplayInside::Flow && !contents.is_replaced() {
Err(replaced) => Arc::new(InlineLevelBox::Atomic( // We found un inline box.
// Whatever happened before, all we need to do before recurring
// is to remember this ongoing inline level box.
self.ongoing_inline_boxes_stack.push(InlineBox {
style: style.clone(),
first_fragment: true,
last_fragment: false,
children: vec![],
});
// `unwrap` doesnt panic here because `is_replaced` returned `false`.
NonReplacedContents::try_from(contents).unwrap().traverse(&style, self.context, self);
let mut inline_box = self
.ongoing_inline_boxes_stack
.pop()
.expect("no ongoing inline level box found");
inline_box.last_fragment = true;
Arc::new(InlineLevelBox::InlineBox(inline_box))
} else {
let request_content_sizes = style.inline_size_is_auto();
Arc::new(InlineLevelBox::Atomic(
IndependentFormattingContext::construct( IndependentFormattingContext::construct(
self.context, self.context,
style.clone(), style.clone(),
display_inside, display_inside,
<Contents<Node>>::Replaced(replaced), contents,
false, // ignored request_content_sizes,
), ),
)), ))
Ok(non_replaced) => match display_inside {
DisplayInside::Flow |
// TODO: Properly implement display: inline-block.
DisplayInside::FlowRoot => {
// Whatever happened before, we just found an inline level element, so
// all we need to do is to remember this ongoing inline level box.
self.ongoing_inline_boxes_stack.push(InlineBox {
style: style.clone(),
first_fragment: true,
last_fragment: false,
children: vec![],
});
NonReplacedContents::traverse(non_replaced, &style, self.context, self);
let mut inline_box = self
.ongoing_inline_boxes_stack
.pop()
.expect("no ongoing inline level box found");
inline_box.last_fragment = true;
Arc::new(InlineLevelBox::InlineBox(inline_box))
},
},
}; };
self.current_inline_level_boxes().push(box_.clone()); self.current_inline_level_boxes().push(box_.clone());
box_ box_