mirror of
https://github.com/servo/servo.git
synced 2025-09-10 15:08:21 +01:00
layout: Simplify effective_overflow()
a little (#39172)
This implements the Default trait for `AxesOverflow`, to avoid having to manually set both axes to `Overflow::Visible`. Also implements the conversion from `&ComputedValues` to `AxesOverflow`, which is the also used for overflow viewport propagation. And moves the `is_inline_box()` checkinto the `ignores_overflow` logic. Testing: Not needed, no change in behavior Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
c490033c52
commit
506e186d03
2 changed files with 55 additions and 58 deletions
|
@ -31,7 +31,7 @@ use crate::fragment_tree::{FragmentFlags, FragmentTree};
|
||||||
use crate::geom::{LogicalVec2, PhysicalSize};
|
use crate::geom::{LogicalVec2, PhysicalSize};
|
||||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
|
||||||
use crate::replaced::ReplacedContents;
|
use crate::replaced::ReplacedContents;
|
||||||
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside};
|
use crate::style_ext::{AxesOverflow, Display, DisplayGeneratingBox, DisplayInside};
|
||||||
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
|
use crate::taffy::{TaffyItemBox, TaffyItemBoxInner};
|
||||||
use crate::{DefiniteContainingBlock, PropagatedBoxTreeData};
|
use crate::{DefiniteContainingBlock, PropagatedBoxTreeData};
|
||||||
|
|
||||||
|
@ -60,11 +60,10 @@ impl BoxTree {
|
||||||
// > used overflow value of visible.
|
// > used overflow value of visible.
|
||||||
let root_style = root_element.style(&context.style_context);
|
let root_style = root_element.style(&context.style_context);
|
||||||
|
|
||||||
let mut viewport_overflow_x = root_style.clone_overflow_x();
|
let mut viewport_overflow = AxesOverflow::from(&*root_style);
|
||||||
let mut viewport_overflow_y = root_style.clone_overflow_y();
|
|
||||||
let mut element_propagating_overflow = root_element;
|
let mut element_propagating_overflow = root_element;
|
||||||
if viewport_overflow_x == Overflow::Visible &&
|
if viewport_overflow.x == Overflow::Visible &&
|
||||||
viewport_overflow_y == Overflow::Visible &&
|
viewport_overflow.y == Overflow::Visible &&
|
||||||
!root_style.get_box().display.is_none()
|
!root_style.get_box().display.is_none()
|
||||||
{
|
{
|
||||||
for child in root_element.children() {
|
for child in root_element.children() {
|
||||||
|
@ -77,8 +76,7 @@ impl BoxTree {
|
||||||
|
|
||||||
let style = child.style(&context.style_context);
|
let style = child.style(&context.style_context);
|
||||||
if !style.get_box().display.is_none() {
|
if !style.get_box().display.is_none() {
|
||||||
viewport_overflow_x = style.clone_overflow_x();
|
viewport_overflow = AxesOverflow::from(&*style);
|
||||||
viewport_overflow_y = style.clone_overflow_y();
|
|
||||||
element_propagating_overflow = child;
|
element_propagating_overflow = child;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -112,8 +110,8 @@ impl BoxTree {
|
||||||
// > If visible is applied to the viewport, it must be interpreted as auto.
|
// > If visible is applied to the viewport, it must be interpreted as auto.
|
||||||
// > If clip is applied to the viewport, it must be interpreted as hidden.
|
// > If clip is applied to the viewport, it must be interpreted as hidden.
|
||||||
viewport_scroll_sensitivity: AxesScrollSensitivity {
|
viewport_scroll_sensitivity: AxesScrollSensitivity {
|
||||||
x: viewport_overflow_x.to_scrollable().into(),
|
x: viewport_overflow.x.to_scrollable().into(),
|
||||||
y: viewport_overflow_y.to_scrollable().into(),
|
y: viewport_overflow.y.to_scrollable().into(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,24 @@ pub struct AxesOverflow {
|
||||||
pub y: Overflow,
|
pub y: Overflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for AxesOverflow {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
x: Overflow::Visible,
|
||||||
|
y: Overflow::Visible,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ComputedValues> for AxesOverflow {
|
||||||
|
fn from(style: &ComputedValues) -> Self {
|
||||||
|
Self {
|
||||||
|
x: style.clone_overflow_x(),
|
||||||
|
y: style.clone_overflow_y(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DisplayGeneratingBox {
|
impl DisplayGeneratingBox {
|
||||||
pub(crate) fn display_inside(&self) -> DisplayInside {
|
pub(crate) fn display_inside(&self) -> DisplayInside {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -594,79 +612,60 @@ impl ComputedValuesExt for ComputedValues {
|
||||||
/// flex containers, and grid containers. And some box types only accept a few values.
|
/// flex containers, and grid containers. And some box types only accept a few values.
|
||||||
/// <https://www.w3.org/TR/css-overflow-3/#overflow-control>
|
/// <https://www.w3.org/TR/css-overflow-3/#overflow-control>
|
||||||
fn effective_overflow(&self, fragment_flags: FragmentFlags) -> AxesOverflow {
|
fn effective_overflow(&self, fragment_flags: FragmentFlags) -> AxesOverflow {
|
||||||
let style_box = self.get_box();
|
|
||||||
let mut overflow_x = style_box.overflow_x;
|
|
||||||
let mut overflow_y = style_box.overflow_y;
|
|
||||||
|
|
||||||
// Inline boxes should never establish scroll containers.
|
|
||||||
if self.is_inline_box(fragment_flags) {
|
|
||||||
return AxesOverflow {
|
|
||||||
x: Overflow::Visible,
|
|
||||||
y: Overflow::Visible,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://www.w3.org/TR/css-overflow-3/#overflow-propagation
|
// https://www.w3.org/TR/css-overflow-3/#overflow-propagation
|
||||||
// The element from which the value is propagated must then have a used overflow value of visible.
|
// The element from which the value is propagated must then have a used overflow value of visible.
|
||||||
if fragment_flags.contains(FragmentFlags::PROPAGATED_OVERFLOW_TO_VIEWPORT) {
|
if fragment_flags.contains(FragmentFlags::PROPAGATED_OVERFLOW_TO_VIEWPORT) {
|
||||||
return AxesOverflow {
|
return AxesOverflow::default();
|
||||||
x: Overflow::Visible,
|
|
||||||
y: Overflow::Visible,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut overflow = AxesOverflow::from(self);
|
||||||
|
|
||||||
// From <https://www.w3.org/TR/css-overflow-4/#overflow-control>:
|
// From <https://www.w3.org/TR/css-overflow-4/#overflow-control>:
|
||||||
// "On replaced elements, the used values of all computed values other than visible is clip."
|
// "On replaced elements, the used values of all computed values other than visible is clip."
|
||||||
if fragment_flags.contains(FragmentFlags::IS_REPLACED) {
|
if fragment_flags.contains(FragmentFlags::IS_REPLACED) {
|
||||||
if overflow_x != Overflow::Visible {
|
if overflow.x != Overflow::Visible {
|
||||||
overflow_x = Overflow::Clip;
|
overflow.x = Overflow::Clip;
|
||||||
}
|
}
|
||||||
if overflow_y != Overflow::Visible {
|
if overflow.y != Overflow::Visible {
|
||||||
overflow_y = Overflow::Clip;
|
overflow.y = Overflow::Clip;
|
||||||
}
|
}
|
||||||
return AxesOverflow {
|
return overflow;
|
||||||
x: overflow_x,
|
|
||||||
y: overflow_y,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let ignores_overflow = match style_box.display.inside() {
|
let ignores_overflow = match self.get_box().display.inside() {
|
||||||
|
// <https://drafts.csswg.org/css-overflow-3/#overflow-control>
|
||||||
|
// `overflow` doesn't apply to inline boxes.
|
||||||
|
stylo::DisplayInside::Flow => self.is_inline_box(fragment_flags),
|
||||||
|
|
||||||
|
// According to <https://drafts.csswg.org/css-tables/#global-style-overrides>,
|
||||||
|
// - overflow applies to table-wrapper boxes and not to table grid boxes.
|
||||||
|
// That's what Blink and WebKit do, however Firefox matches a CSSWG resolution that says
|
||||||
|
// the opposite: <https://lists.w3.org/Archives/Public/www-style/2012Aug/0298.html>
|
||||||
|
// Due to the way that we implement table-wrapper boxes, it's easier to align with Firefox.
|
||||||
|
// - Tables ignore overflow values different than visible, clip and hidden.
|
||||||
|
// This affects both axes, to ensure they have the same scrollability.
|
||||||
stylo::DisplayInside::Table => {
|
stylo::DisplayInside::Table => {
|
||||||
// According to <https://drafts.csswg.org/css-tables/#global-style-overrides>,
|
|
||||||
// - overflow applies to table-wrapper boxes and not to table grid boxes.
|
|
||||||
// That's what Blink and WebKit do, however Firefox matches a CSSWG resolution that says
|
|
||||||
// the opposite: <https://lists.w3.org/Archives/Public/www-style/2012Aug/0298.html>
|
|
||||||
// Due to the way that we implement table-wrapper boxes, it's easier to align with Firefox.
|
|
||||||
// - Tables ignore overflow values different than visible, clip and hidden.
|
|
||||||
// This affects both axes, to ensure they have the same scrollability.
|
|
||||||
!matches!(self.pseudo(), Some(PseudoElement::ServoTableGrid)) ||
|
!matches!(self.pseudo(), Some(PseudoElement::ServoTableGrid)) ||
|
||||||
matches!(overflow_x, Overflow::Auto | Overflow::Scroll) ||
|
matches!(overflow.x, Overflow::Auto | Overflow::Scroll) ||
|
||||||
matches!(overflow_y, Overflow::Auto | Overflow::Scroll)
|
matches!(overflow.y, Overflow::Auto | Overflow::Scroll)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// <https://drafts.csswg.org/css-tables/#global-style-overrides>
|
||||||
|
// Table-track and table-track-group boxes ignore overflow.
|
||||||
stylo::DisplayInside::TableColumn |
|
stylo::DisplayInside::TableColumn |
|
||||||
stylo::DisplayInside::TableColumnGroup |
|
stylo::DisplayInside::TableColumnGroup |
|
||||||
stylo::DisplayInside::TableRow |
|
stylo::DisplayInside::TableRow |
|
||||||
stylo::DisplayInside::TableRowGroup |
|
stylo::DisplayInside::TableRowGroup |
|
||||||
stylo::DisplayInside::TableHeaderGroup |
|
stylo::DisplayInside::TableHeaderGroup |
|
||||||
stylo::DisplayInside::TableFooterGroup => {
|
stylo::DisplayInside::TableFooterGroup => true,
|
||||||
// <https://drafts.csswg.org/css-tables/#global-style-overrides>
|
|
||||||
// Table-track and table-track-group boxes ignore overflow.
|
|
||||||
true
|
|
||||||
},
|
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if ignores_overflow {
|
if ignores_overflow {
|
||||||
AxesOverflow {
|
return AxesOverflow::default();
|
||||||
x: Overflow::Visible,
|
|
||||||
y: Overflow::Visible,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AxesOverflow {
|
|
||||||
x: overflow_x,
|
|
||||||
y: overflow_y,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
overflow
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if this style is a normal block and establishes
|
/// Return true if this style is a normal block and establishes
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue