Allow list markers to contain multiple fragments

Fixes #6913.
This commit is contained in:
Matt Brubeck 2015-08-06 09:32:30 -07:00
parent b4e30da3db
commit 4e8d2b0e38
3 changed files with 21 additions and 20 deletions

View file

@ -1164,18 +1164,18 @@ impl<'a> FlowConstructor<'a> {
fn build_flow_for_list_item(&mut self, node: &ThreadSafeLayoutNode, flotation: float::T) fn build_flow_for_list_item(&mut self, node: &ThreadSafeLayoutNode, flotation: float::T)
-> ConstructionResult { -> ConstructionResult {
let flotation = FloatKind::from_property(flotation); let flotation = FloatKind::from_property(flotation);
let marker_fragment = match node.style().get_list().list_style_image.0 { let marker_fragments = match node.style().get_list().list_style_image.0 {
Some(ref url) => { Some(ref url) => {
let image_info = box ImageFragmentInfo::new(node, let image_info = box ImageFragmentInfo::new(node,
Some((*url).clone()), Some((*url).clone()),
&self.layout_context); &self.layout_context);
Some(Fragment::new(node, SpecificFragmentInfo::Image(image_info))) vec![Fragment::new(node, SpecificFragmentInfo::Image(image_info))]
} }
None => { None => {
match ListStyleTypeContent::from_list_style_type(node.style() match ListStyleTypeContent::from_list_style_type(node.style()
.get_list() .get_list()
.list_style_type) { .list_style_type) {
ListStyleTypeContent::None => None, ListStyleTypeContent::None => Vec::new(),
ListStyleTypeContent::StaticText(ch) => { ListStyleTypeContent::StaticText(ch) => {
let text = format!("{}\u{a0}", ch); let text = format!("{}\u{a0}", ch);
let mut unscanned_marker_fragments = LinkedList::new(); let mut unscanned_marker_fragments = LinkedList::new();
@ -1186,11 +1186,10 @@ impl<'a> FlowConstructor<'a> {
let marker_fragments = TextRunScanner::new().scan_for_runs( let marker_fragments = TextRunScanner::new().scan_for_runs(
&mut self.layout_context.font_context(), &mut self.layout_context.font_context(),
unscanned_marker_fragments); unscanned_marker_fragments);
debug_assert!(marker_fragments.len() == 1); marker_fragments.fragments
marker_fragments.fragments.into_iter().next()
} }
ListStyleTypeContent::GeneratedContent(info) => { ListStyleTypeContent::GeneratedContent(info) => {
Some(Fragment::new(node, SpecificFragmentInfo::GeneratedContent(info))) vec![Fragment::new(node, SpecificFragmentInfo::GeneratedContent(info))]
} }
} }
} }
@ -1206,14 +1205,14 @@ impl<'a> FlowConstructor<'a> {
let flow = match node.style().get_list().list_style_position { let flow = match node.style().get_list().list_style_position {
list_style_position::T::outside => { list_style_position::T::outside => {
box ListItemFlow::from_fragments_and_flotation(main_fragment, box ListItemFlow::from_fragments_and_flotation(main_fragment,
marker_fragment, marker_fragments,
flotation) flotation)
} }
list_style_position::T::inside => { list_style_position::T::inside => {
if let Some(marker_fragment) = marker_fragment { for marker_fragment in marker_fragments {
initial_fragments.fragments.push_back(marker_fragment) initial_fragments.fragments.push_back(marker_fragment)
} }
box ListItemFlow::from_fragments_and_flotation(main_fragment, None, flotation) box ListItemFlow::from_fragments_and_flotation(main_fragment, vec![], flotation)
} }
}; };

View file

@ -1734,7 +1734,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
mut display_list: Box<DisplayList>, mut display_list: Box<DisplayList>,
layout_context: &LayoutContext) { layout_context: &LayoutContext) {
// Draw the marker, if applicable. // Draw the marker, if applicable.
if let Some(ref mut marker) = self.marker { for marker in &mut self.marker_fragments {
marker.build_display_list(&mut *display_list, marker.build_display_list(&mut *display_list,
layout_context, layout_context,
&self.block_flow.base.stacking_relative_position, &self.block_flow.base.stacking_relative_position,

View file

@ -34,20 +34,20 @@ pub struct ListItemFlow {
pub block_flow: BlockFlow, pub block_flow: BlockFlow,
/// The marker, if outside. (Markers that are inside are instead just fragments on the interior /// The marker, if outside. (Markers that are inside are instead just fragments on the interior
/// `InlineFlow`.) /// `InlineFlow`.)
pub marker: Option<Fragment>, pub marker_fragments: Vec<Fragment>,
} }
impl ListItemFlow { impl ListItemFlow {
pub fn from_fragments_and_flotation(main_fragment: Fragment, pub fn from_fragments_and_flotation(main_fragment: Fragment,
marker_fragment: Option<Fragment>, marker_fragments: Vec<Fragment>,
flotation: Option<FloatKind>) flotation: Option<FloatKind>)
-> ListItemFlow { -> ListItemFlow {
let mut this = ListItemFlow { let mut this = ListItemFlow {
block_flow: BlockFlow::from_fragment(main_fragment, flotation), block_flow: BlockFlow::from_fragment(main_fragment, flotation),
marker: marker_fragment, marker_fragments: marker_fragments,
}; };
if let Some(ref marker) = this.marker { if let Some(ref marker) = this.marker_fragments.first() {
match marker.style().get_list().list_style_type { match marker.style().get_list().list_style_type {
list_style_type::T::disc | list_style_type::T::disc |
list_style_type::T::none | list_style_type::T::none |
@ -84,7 +84,9 @@ impl Flow for ListItemFlow {
fn assign_inline_sizes(&mut self, layout_context: &LayoutContext) { fn assign_inline_sizes(&mut self, layout_context: &LayoutContext) {
self.block_flow.assign_inline_sizes(layout_context); self.block_flow.assign_inline_sizes(layout_context);
if let Some(ref mut marker) = self.marker { let mut marker_inline_start = self.block_flow.fragment.border_box.start.i;
for marker in self.marker_fragments.iter_mut().rev() {
let containing_block_inline_size = self.block_flow.base.block_container_inline_size; let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
marker.assign_replaced_inline_size_if_necessary(containing_block_inline_size); marker.assign_replaced_inline_size_if_necessary(containing_block_inline_size);
@ -94,15 +96,15 @@ impl Flow for ListItemFlow {
marker.border_box.size.inline = marker.border_box.size.inline =
intrinsic_inline_sizes.content_intrinsic_sizes.preferred_inline_size; intrinsic_inline_sizes.content_intrinsic_sizes.preferred_inline_size;
marker.border_box.start.i = self.block_flow.fragment.border_box.start.i - marker_inline_start = marker_inline_start - marker.border_box.size.inline;
marker.border_box.size.inline; marker.border_box.start.i = marker_inline_start;
} }
} }
fn assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { fn assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
self.block_flow.assign_block_size(layout_context); self.block_flow.assign_block_size(layout_context);
if let Some(ref mut marker) = self.marker { for marker in &mut self.marker_fragments {
let containing_block_block_size = let containing_block_block_size =
self.block_flow.base.block_container_explicit_block_size; self.block_flow.base.block_container_explicit_block_size;
marker.assign_replaced_block_size_if_necessary(containing_block_block_size); marker.assign_replaced_block_size_if_necessary(containing_block_block_size);
@ -161,7 +163,7 @@ impl Flow for ListItemFlow {
stacking_context_position: &Point2D<Au>) { stacking_context_position: &Point2D<Au>) {
self.block_flow.iterate_through_fragment_border_boxes(iterator, level, stacking_context_position); self.block_flow.iterate_through_fragment_border_boxes(iterator, level, stacking_context_position);
if let Some(ref marker) = self.marker { for marker in &self.marker_fragments {
if iterator.should_process(marker) { if iterator.should_process(marker) {
iterator.process( iterator.process(
marker, marker,
@ -186,7 +188,7 @@ impl Flow for ListItemFlow {
fn mutate_fragments(&mut self, mutator: &mut FnMut(&mut Fragment)) { fn mutate_fragments(&mut self, mutator: &mut FnMut(&mut Fragment)) {
self.block_flow.mutate_fragments(mutator); self.block_flow.mutate_fragments(mutator);
if let Some(ref mut marker) = self.marker { for marker in &mut self.marker_fragments {
(*mutator)(marker) (*mutator)(marker)
} }
} }