From 0dfd45ba2153bda841a32a48938ecadfeb3f1999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 7 Sep 2022 23:57:18 +0000 Subject: [PATCH] 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 --- components/style/style_adjuster.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index b855b937dfb..09bdb2a6522 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -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")]