style: Make -webkit-line-clamp create a block container in the appropriate situations

This is a hack, sorta, similar to Chromium's:

  https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/layout/layout_object.cc;l=356;drc=312b74e385e6aba98ab31fd911238c0dc16b396c

except at computed-value rather than used-value time, because it's both
simpler to reason about and prevents lying in the computed style.

This fixes the relevant test-case, and matches closer what Chromium does,
by not creating anonymous flex items for all elements inside the
line-clamp context.

The behavior change is covered by the test changes. I had to also fix a
couple pre-existing bugs that were caught by tests, now that the
line-clamped block is the -webkit-box-styled element rather than an anonymous
flex item (and thus now had padding).

Depends on D155180

Differential Revision: https://phabricator.services.mozilla.com/D155181
This commit is contained in:
Emilio Cobos Álvarez 2022-09-07 23:57:18 +00:00 committed by Martin Robinson
parent 069304c99c
commit 0dfd45ba21

View file

@ -150,6 +150,35 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
}
}
/// -webkit-box with line-clamp and vertical orientation gets turned into
/// flow-root at computed-value time.
///
/// This makes the element not be a flex container, with all that it
/// implies, but it should be safe. It matches blink, see
/// https://bugzilla.mozilla.org/show_bug.cgi?id=1786147#c10
fn adjust_for_webkit_line_clamp(&mut self) {
use crate::properties::longhands::_moz_box_orient::computed_value::T as BoxOrient;
use crate::values::specified::box_::{DisplayOutside, DisplayInside};
let box_style= self.style.get_box();
if box_style.clone__webkit_line_clamp().is_none() {
return;
}
let disp = box_style.clone_display();
if disp.inside() != DisplayInside::WebkitBox {
return;
}
if self.style.get_xul().clone__moz_box_orient() != BoxOrient::Vertical {
return;
}
let new_display = if disp.outside() == DisplayOutside::Block {
Display::FlowRoot
} else {
debug_assert_eq!(disp.outside(), DisplayOutside::Inline);
Display::InlineBlock
};
self.style.mutate_box().set_adjusted_display(new_display, false);
}
/// CSS 2.1 section 9.7:
///
/// If 'position' has the value 'absolute' or 'fixed', [...] the computed
@ -856,6 +885,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
}
self.adjust_for_top_layer();
self.blockify_if_necessary(layout_parent_style, element);
self.adjust_for_webkit_line_clamp();
self.adjust_for_position();
self.adjust_for_overflow();
#[cfg(feature = "gecko")]