diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index 0fddde1494a..a658aebb3e9 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -63,6 +63,56 @@ impl ListItemFlow { this } + + /// Assign inline size and position for the marker. This is done during the `assign_block_size` + /// traversal because floats will impact the marker position. Therefore we need to have already + /// called `assign_block_size` on the list item's block flow, in order to know which floats + /// impact the position. + /// + /// Per CSS 2.1 § 12.5.1, the marker position is not precisely specified, but it must be on the + /// left side of the content (for ltr direction). However, flowing the marker around floats + /// matches the rendering of Gecko and Blink. + fn assign_marker_inline_sizes(&mut self, layout_context: &LayoutContext) { + let base = &self.block_flow.base; + let available_rect = base.floats.available_rect( + -base.position.size.block, + base.position.size.block, + base.block_container_inline_size); + let mut marker_inline_start = available_rect.unwrap_or(self.block_flow.fragment.border_box).start.i; + + for marker in self.marker_fragments.iter_mut().rev() { + let container_block_size = + self.block_flow.explicit_block_containing_size(layout_context.shared_context()); + marker.assign_replaced_inline_size_if_necessary(base.block_container_inline_size, container_block_size); + + // Do this now. There's no need to do this in bubble-widths, since markers do not + // contribute to the inline size of this flow. + let intrinsic_inline_sizes = marker.compute_intrinsic_inline_sizes(); + + marker.border_box.size.inline = + intrinsic_inline_sizes.content_intrinsic_sizes.preferred_inline_size; + marker_inline_start = marker_inline_start - marker.border_box.size.inline; + marker.border_box.start.i = marker_inline_start; + } + } + + fn assign_marker_block_sizes(&mut self, layout_context: &LayoutContext) { + // FIXME(pcwalton): Do this during flow construction, like `InlineFlow` does? + let marker_line_metrics = with_thread_local_font_context(layout_context, |font_context| { + InlineFlow::minimum_line_metrics_for_fragments(&self.marker_fragments, + font_context, + &*self.block_flow.fragment.style) + }); + + for marker in &mut self.marker_fragments { + marker.assign_replaced_block_size_if_necessary(); + let marker_inline_metrics = marker.aligned_inline_metrics(layout_context, + &marker_line_metrics, + Some(&marker_line_metrics)); + marker.border_box.start.b = marker_line_metrics.space_above_baseline - + marker_inline_metrics.ascent; + } + } } impl Flow for ListItemFlow { @@ -85,44 +135,12 @@ impl Flow for ListItemFlow { fn assign_inline_sizes(&mut self, layout_context: &LayoutContext) { self.block_flow.assign_inline_sizes(layout_context); - - 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 container_block_size = - self.block_flow.explicit_block_containing_size(layout_context.shared_context()); - marker.assign_replaced_inline_size_if_necessary(containing_block_inline_size, container_block_size); - - // Do this now. There's no need to do this in bubble-widths, since markers do not - // contribute to the inline size of this flow. - let intrinsic_inline_sizes = marker.compute_intrinsic_inline_sizes(); - - marker.border_box.size.inline = - intrinsic_inline_sizes.content_intrinsic_sizes.preferred_inline_size; - marker_inline_start = marker_inline_start - marker.border_box.size.inline; - marker.border_box.start.i = marker_inline_start; - } } fn assign_block_size(&mut self, layout_context: &LayoutContext) { self.block_flow.assign_block_size(layout_context); - - // FIXME(pcwalton): Do this during flow construction, like `InlineFlow` does? - let marker_line_metrics = with_thread_local_font_context(layout_context, |font_context| { - InlineFlow::minimum_line_metrics_for_fragments(&self.marker_fragments, - font_context, - &*self.block_flow.fragment.style) - }); - - for marker in &mut self.marker_fragments { - marker.assign_replaced_block_size_if_necessary(); - let marker_inline_metrics = marker.aligned_inline_metrics(layout_context, - &marker_line_metrics, - Some(&marker_line_metrics)); - marker.border_box.start.b = marker_line_metrics.space_above_baseline - - marker_inline_metrics.ascent; - } + self.assign_marker_inline_sizes(layout_context); + self.assign_marker_block_sizes(layout_context); } fn compute_stacking_relative_position(&mut self, layout_context: &LayoutContext) { diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 22bc7212f2e..8d999c4271e 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -3887,6 +3887,18 @@ {} ] ], + "css/list_item_marker_around_float.html": [ + [ + "/_mozilla/css/list_item_marker_around_float.html", + [ + [ + "/_mozilla/css/list_item_marker_around_float_ref.html", + "==" + ] + ], + {} + ] + ], "css/list_item_overflow.html": [ [ "/_mozilla/css/list_item_overflow.html", @@ -9538,6 +9550,11 @@ {} ] ], + "css/list_item_marker_around_float_ref.html": [ + [ + {} + ] + ], "css/list_item_overflow_ref.html": [ [ {} @@ -63573,6 +63590,14 @@ "958f9315c950502cdadb2297e1ab77e197774113", "support" ], + "css/list_item_marker_around_float.html": [ + "1023fced99e1181fadce849978c4e111da8ad4aa", + "reftest" + ], + "css/list_item_marker_around_float_ref.html": [ + "1c13844df9055d73a8421ca3f8398cb4c289c44e", + "support" + ], "css/list_item_overflow.html": [ "a8aeb2070bb26c8bf1344a8fdb2bc84d8a60a5b4", "reftest" diff --git a/tests/wpt/mozilla/tests/css/list_item_marker_around_float.html b/tests/wpt/mozilla/tests/css/list_item_marker_around_float.html new file mode 100644 index 00000000000..e3eee5b5485 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/list_item_marker_around_float.html @@ -0,0 +1,22 @@ + + + + + + +
+
+ + diff --git a/tests/wpt/mozilla/tests/css/list_item_marker_around_float_ref.html b/tests/wpt/mozilla/tests/css/list_item_marker_around_float_ref.html new file mode 100644 index 00000000000..319cd297739 --- /dev/null +++ b/tests/wpt/mozilla/tests/css/list_item_marker_around_float_ref.html @@ -0,0 +1,35 @@ + + + + + +
+
+ +