style: Fix number input so that it honors overflow-clip-box-block.

This never worked, but it's more visible with the new form controls which have
more padding.

Make the anonymous div and co a pseudo-element, so that they inherit from the
<input> properly in all cases. This works for non-number inputs because the
editor root is a direct child of the <input>, but it doesn't for number inputs
because there's a flex wrapper in between.

This way overflow-clip-box: inherit does what we want. Reset the padding in the
inline direction, as the padding for <input type=number> applies to the arrow
boxes as well, and thus we'd double-apply it.

Differential Revision: https://phabricator.services.mozilla.com/D65271
This commit is contained in:
Emilio Cobos Álvarez 2020-03-18 09:21:44 +00:00
parent ece146988c
commit decc648c46
2 changed files with 36 additions and 9 deletions

View file

@ -134,12 +134,6 @@ impl PseudoElement {
*self == PseudoElement::FirstLine *self == PseudoElement::FirstLine
} }
/// Whether this pseudo-element is ::-moz-fieldset-content.
#[inline]
pub fn is_fieldset_content(&self) -> bool {
*self == PseudoElement::FieldsetContent
}
/// Whether this pseudo-element is the ::-moz-color-swatch pseudo. /// Whether this pseudo-element is the ::-moz-color-swatch pseudo.
#[inline] #[inline]
pub fn is_color_swatch(&self) -> bool { pub fn is_color_swatch(&self) -> bool {

View file

@ -494,6 +494,35 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
} }
} }
/// <textarea>'s editor root needs to inherit the overflow value from its
/// parent, but we need to make sure it's still scrollable.
#[cfg(feature = "gecko")]
fn adjust_for_text_control_editing_root(&mut self) {
use crate::selector_parser::PseudoElement;
if self.style.pseudo != Some(&PseudoElement::MozTextControlEditingRoot) {
return;
}
let box_style = self.style.get_box();
let overflow_x = box_style.clone_overflow_x();
let overflow_y = box_style.clone_overflow_y();
fn scrollable(v: Overflow) -> bool {
v != Overflow::MozHiddenUnscrollable && v != Overflow::Visible
}
// If at least one is scrollable we'll adjust the other one in
// adjust_for_overflow if needed.
if scrollable(overflow_x) || scrollable(overflow_y) {
return;
}
let box_style = self.style.mutate_box();
box_style.set_overflow_x(Overflow::Auto);
box_style.set_overflow_y(Overflow::Auto);
}
/// If a <fieldset> has grid/flex display type, we need to inherit /// If a <fieldset> has grid/flex display type, we need to inherit
/// this type into its ::-moz-fieldset-content anonymous box. /// this type into its ::-moz-fieldset-content anonymous box.
/// ///
@ -502,9 +531,10 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
/// normal cascading process. /// normal cascading process.
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
fn adjust_for_fieldset_content(&mut self, layout_parent_style: &ComputedValues) { fn adjust_for_fieldset_content(&mut self, layout_parent_style: &ComputedValues) {
match self.style.pseudo { use crate::selector_parser::PseudoElement;
Some(ref p) if p.is_fieldset_content() => {},
_ => return, if self.style.pseudo != Some(&PseudoElement::FieldsetContent) {
return;
} }
debug_assert_eq!(self.style.get_box().clone_display(), Display::Block); debug_assert_eq!(self.style.get_box().clone_display(), Display::Block);
@ -786,6 +816,9 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
{ {
self.adjust_for_prohibited_display_contents(element); self.adjust_for_prohibited_display_contents(element);
self.adjust_for_fieldset_content(layout_parent_style); self.adjust_for_fieldset_content(layout_parent_style);
// NOTE: It's important that this happens before
// adjust_for_overflow.
self.adjust_for_text_control_editing_root();
} }
self.adjust_for_top_layer(); self.adjust_for_top_layer();
self.blockify_if_necessary(layout_parent_style, element); self.blockify_if_necessary(layout_parent_style, element);