From d86490d481874e4d84c198d8972466bc36fef2e2 Mon Sep 17 00:00:00 2001 From: Alaska Date: Sat, 9 Dec 2023 20:35:44 +0100 Subject: [PATCH] web/core: Represent float property as an Option This makes sense intuitively, because when handling floats we first check whether the box is even floating (builder.rs) but don't want to worry about the float:none case afterwards. --- crates/web/core/properties.json | 2 +- .../web/core/src/css/layout/flow/builder.rs | 13 +++---- crates/web/core/src/css/layout/flow/float.rs | 36 ++++++++----------- crates/web/core/src/css/values/float.rs | 27 +++++++++----- crates/web/core/src/css/values/mod.rs | 2 +- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/crates/web/core/properties.json b/crates/web/core/properties.json index ea951112..fd3761eb 100644 --- a/crates/web/core/properties.json +++ b/crates/web/core/properties.json @@ -75,7 +75,7 @@ "specification": "https://drafts.csswg.org/css2/#propdef-float", "inherited": false, "value": "Float", - "initial": "Float::None" + "initial": "Float::default()" }, { "name": "font-family", diff --git a/crates/web/core/src/css/layout/flow/builder.rs b/crates/web/core/src/css/layout/flow/builder.rs index 9c1b9cc0..5f067ac4 100644 --- a/crates/web/core/src/css/layout/flow/builder.rs +++ b/crates/web/core/src/css/layout/flow/builder.rs @@ -9,7 +9,7 @@ use crate::{ BlockContainer, BlockLevelBox, InFlowBlockBox, InlineBox, InlineFormattingContext, InlineLevelBox, }, - values, ComputedStyle, StyleComputer, + ComputedStyle, StyleComputer, }, dom::{dom_objects, DomPtr}, }; @@ -162,8 +162,9 @@ impl<'stylesheets, 'parent_style> BoxTreeBuilder<'stylesheets, 'parent_style> { let content = BoxTreeBuilder::build(node.clone(), self.style_computer, &style); let position = style.position(); - let block_box = match style.float() { - values::Float::None => { + let block_box = match style.float().side() { + Some(side) => float::FloatingBox::new(node, style, side, content).into(), + None => { if position.is_absolute() || position.is_fixed() { AbsolutelyPositionedBox { style, @@ -175,12 +176,6 @@ impl<'stylesheets, 'parent_style> BoxTreeBuilder<'stylesheets, 'parent_style> { InFlowBlockBox::new(style, Some(node), content).into() } }, - values::Float::Left => { - float::FloatingBox::new(node, style, float::Side::Left, content).into() - }, - values::Float::Right => { - float::FloatingBox::new(node, style, float::Side::Right, content).into() - }, }; self.block_level_boxes.push(block_box); } diff --git a/crates/web/core/src/css/layout/flow/float.rs b/crates/web/core/src/css/layout/flow/float.rs index d8488fc9..30f3c3cf 100644 --- a/crates/web/core/src/css/layout/flow/float.rs +++ b/crates/web/core/src/css/layout/flow/float.rs @@ -13,7 +13,7 @@ use crate::{ values::{ self, length::{self, Length}, - AutoOr, PercentageOr, + AutoOr, FloatSide, PercentageOr, }, }, dom::{dom_objects, DomPtr}, @@ -28,7 +28,7 @@ use super::BlockContainer; pub struct FloatingBox { pub node: DomPtr, pub style: ComputedStyle, - pub side: Side, + pub side: FloatSide, pub contents: BlockContainer, } @@ -37,7 +37,7 @@ impl FloatingBox { pub fn new( node: DomPtr, style: ComputedStyle, - side: Side, + side: FloatSide, contents: BlockContainer, ) -> Self { Self { @@ -223,16 +223,16 @@ impl FloatContext { /// Place a float in a given position. /// /// `y_offset` describes the offset within the height of the content band specified by `content_band_index`. - fn place_float(&mut self, margin_area: Size, side: Side, placement: Placement) { + fn place_float(&mut self, margin_area: Size, side: FloatSide, placement: Placement) { // Split the content band in up to three new bands let old_content_band = self.content_bands.remove(placement.band_index); let (new_inset_left, new_inset_right) = match side { - Side::Left => { + FloatSide::Left => { let inset_left = Some(old_content_band.inset_left.unwrap_or_default() + margin_area.width); (inset_left, old_content_band.inset_right) }, - Side::Right => { + FloatSide::Right => { let inset_right = Some(old_content_band.inset_right.unwrap_or_default() + margin_area.width); (old_content_band.inset_left, inset_right) @@ -272,16 +272,16 @@ impl FloatContext { self.lower_float_ceiling(placement.position.y); match side { - Side::Left => { + FloatSide::Left => { self.lowest_float_left = placement.position.y + margin_area.height; }, - Side::Right => { + FloatSide::Right => { self.lowest_float_right = placement.position.y + margin_area.height; }, } } - fn find_position_for_float(&self, float_width: Pixels, side: Side) -> Placement { + fn find_position_for_float(&self, float_width: Pixels, side: FloatSide) -> Placement { debug_assert!(!self.content_bands.is_empty()); let mut cursor = Pixels::ZERO; @@ -312,8 +312,8 @@ impl FloatContext { let chosen_band = &self.content_bands[band_to_place_float_in]; let y_position = cmp::max(cursor, self.float_ceiling); let x_position = match side { - Side::Left => chosen_band.inset_left.unwrap_or_default(), - Side::Right => { + FloatSide::Left => chosen_band.inset_left.unwrap_or_default(), + FloatSide::Right => { self.containing_block.width() - float_width - chosen_band.inset_right.unwrap_or_default() @@ -335,7 +335,7 @@ impl FloatContext { pub fn find_position_and_place_float_box( &mut self, margin_area: Size, - side: Side, + side: FloatSide, ) -> Vec2D { let placement = self.find_position_for_float(margin_area.width, side); self.place_float(margin_area, side, placement); @@ -350,12 +350,6 @@ struct Placement { offset_in_band: Pixels, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum Side { - Left, - Right, -} - /// A rectangular area where content may be placed #[derive(Clone, Debug)] struct ContentBand { @@ -368,7 +362,7 @@ impl ContentBand { fn box_fits( &self, box_width: Pixels, - place_on_side: Side, + place_on_side: FloatSide, width_of_containing_block: Pixels, ) -> bool { // The algorithm is the same for left- and right-floating boxes. @@ -376,8 +370,8 @@ impl ContentBand { // and switch the insets on the two sides if necessary let (this_side, opposing_side) = match place_on_side { - Side::Left => (self.inset_left, self.inset_right), - Side::Right => (self.inset_right, self.inset_left), + FloatSide::Left => (self.inset_left, self.inset_right), + FloatSide::Right => (self.inset_right, self.inset_left), }; let position = this_side.unwrap_or_default(); diff --git a/crates/web/core/src/css/values/float.rs b/crates/web/core/src/css/values/float.rs index 008229c4..d4f59958 100644 --- a/crates/web/core/src/css/values/float.rs +++ b/crates/web/core/src/css/values/float.rs @@ -4,22 +4,33 @@ use crate::{ }; /// -#[derive(Clone, Copy, Debug)] -pub enum Float { +#[derive(Clone, Copy, Debug, Default)] +pub struct Float { + side: Option, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum FloatSide { Left, Right, - None, +} + +impl Float { + #[must_use] + pub fn side(&self) -> Option { + self.side + } } impl<'a> CSSParse<'a> for Float { fn parse(parser: &mut Parser<'a>) -> Result { - let value = match parser.expect_identifier()? { - static_interned!("left") => Self::Left, - static_interned!("right") => Self::Right, - static_interned!("none") => Self::None, + let side = match parser.expect_identifier()? { + static_interned!("left") => Some(FloatSide::Left), + static_interned!("right") => Some(FloatSide::Right), + static_interned!("none") => None, _ => return Err(ParseError), }; - Ok(value) + Ok(Self { side }) } } diff --git a/crates/web/core/src/css/values/mod.rs b/crates/web/core/src/css/values/mod.rs index 4a921357..a34bd223 100644 --- a/crates/web/core/src/css/values/mod.rs +++ b/crates/web/core/src/css/values/mod.rs @@ -21,7 +21,7 @@ pub use background_color::BackgroundColor; pub use border::{Border, LineStyle, LineWidth}; pub use color::Color; pub use display::Display; -pub use float::{Clear, Float}; +pub use float::{Clear, Float, FloatSide}; pub use font_family::{FontFamily, FontName}; pub use font_size::FontSize; pub use font_style::FontStyle;