diff options
Diffstat (limited to 'components/layout/block.rs')
-rw-r--r-- | components/layout/block.rs | 2380 |
1 files changed, 1487 insertions, 893 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index 00759909063..ae1bc242e32 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -93,15 +93,16 @@ struct BSizeConstraintSolution { block_start: Au, block_size: Au, margin_block_start: Au, - margin_block_end: Au + margin_block_end: Au, } impl BSizeConstraintSolution { - fn new(block_start: Au, - block_size: Au, - margin_block_start: Au, - margin_block_end: Au) - -> BSizeConstraintSolution { + fn new( + block_start: Au, + block_size: Au, + margin_block_start: Au, + margin_block_end: Au, + ) -> BSizeConstraintSolution { BSizeConstraintSolution { block_start: block_start, block_size: block_size, @@ -119,14 +120,15 @@ impl BSizeConstraintSolution { /// [aka available_block-size] /// /// Return the solution for the equation. - fn solve_vertical_constraints_abs_nonreplaced(block_size: MaybeAuto, - block_start_margin: MaybeAuto, - block_end_margin: MaybeAuto, - block_start: MaybeAuto, - block_end: MaybeAuto, - content_block_size: Au, - available_block_size: Au) - -> BSizeConstraintSolution { + fn solve_vertical_constraints_abs_nonreplaced( + block_size: MaybeAuto, + block_start_margin: MaybeAuto, + block_end_margin: MaybeAuto, + block_start: MaybeAuto, + block_end: MaybeAuto, + content_block_size: Au, + available_block_size: Au, + ) -> BSizeConstraintSolution { let (block_start, block_size, margin_block_start, margin_block_end) = match (block_start, block_end, block_size) { (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { @@ -137,64 +139,103 @@ impl BSizeConstraintSolution { let block_size = content_block_size; // Use a dummy value for `block_start`, since it has the static position. (Au(0), block_size, margin_block_start, margin_block_end) - } - (MaybeAuto::Specified(block_start), - MaybeAuto::Specified(block_end), - MaybeAuto::Specified(block_size)) => { + }, + ( + MaybeAuto::Specified(block_start), + MaybeAuto::Specified(block_end), + MaybeAuto::Specified(block_size), + ) => { match (block_start_margin, block_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { let total_margin_val = available_block_size - block_start - block_end - block_size; - (block_start, - block_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) - } + ( + block_start, + block_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) + }, (MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => { let sum = block_start + block_end + block_size + margin_block_start; - (block_start, - block_size, - margin_block_start, - available_block_size - sum) - } + ( + block_start, + block_size, + margin_block_start, + available_block_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => { let sum = block_start + block_end + block_size + margin_block_end; - (block_start, block_size, available_block_size - sum, margin_block_end) - } - (MaybeAuto::Specified(margin_block_start), - MaybeAuto::Specified(margin_block_end)) => { + ( + block_start, + block_size, + available_block_size - sum, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(margin_block_start), + MaybeAuto::Specified(margin_block_end), + ) => { // Values are over-constrained. Ignore value for 'block-end'. - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, } - } + }, // For the rest of the cases, auto values for margin are set to 0 // If only one is Auto, solve for it - (MaybeAuto::Auto, - MaybeAuto::Specified(block_end), - MaybeAuto::Specified(block_size)) => { + ( + MaybeAuto::Auto, + MaybeAuto::Specified(block_end), + MaybeAuto::Specified(block_size), + ) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let sum = block_end + block_size + margin_block_start + margin_block_end; - (available_block_size - sum, block_size, margin_block_start, margin_block_end) - } - (MaybeAuto::Specified(block_start), - MaybeAuto::Auto, - MaybeAuto::Specified(block_size)) => { + ( + available_block_size - sum, + block_size, + margin_block_start, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(block_start), + MaybeAuto::Auto, + MaybeAuto::Specified(block_size), + ) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); - (block_start, block_size, margin_block_start, margin_block_end) - } - (MaybeAuto::Specified(block_start), - MaybeAuto::Specified(block_end), - MaybeAuto::Auto) => { + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(block_start), + MaybeAuto::Specified(block_end), + MaybeAuto::Auto, + ) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let sum = block_start + block_end + margin_block_start + margin_block_end; - (block_start, available_block_size - sum, margin_block_start, margin_block_end) - } + ( + block_start, + available_block_size - sum, + margin_block_start, + margin_block_end, + ) + }, // If block-size is auto, then block-size is content block-size. Solve for the // non-auto value. @@ -202,25 +243,40 @@ impl BSizeConstraintSolution { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let block_size = content_block_size; - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(block_end), MaybeAuto::Auto) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let block_size = content_block_size; let sum = block_end + block_size + margin_block_start + margin_block_end; - (available_block_size - sum, block_size, margin_block_start, margin_block_end) - } + ( + available_block_size - sum, + block_size, + margin_block_start, + margin_block_end, + ) + }, (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); // Use a dummy value for `block_start`, since it has the static position. (Au(0), block_size, margin_block_start, margin_block_end) - } + }, }; - BSizeConstraintSolution::new(block_start, block_size, margin_block_start, margin_block_end) + BSizeConstraintSolution::new( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) } /// Solve the vertical constraint equation for absolute replaced elements. @@ -234,14 +290,15 @@ impl BSizeConstraintSolution { /// [aka available block-size] /// /// Return the solution for the equation. - fn solve_vertical_constraints_abs_replaced(block_size: Au, - block_start_margin: MaybeAuto, - block_end_margin: MaybeAuto, - block_start: MaybeAuto, - block_end: MaybeAuto, - _: Au, - available_block_size: Au) - -> BSizeConstraintSolution { + fn solve_vertical_constraints_abs_replaced( + block_size: Au, + block_start_margin: MaybeAuto, + block_end_margin: MaybeAuto, + block_start: MaybeAuto, + block_end: MaybeAuto, + _: Au, + available_block_size: Au, + ) -> BSizeConstraintSolution { let (block_start, block_size, margin_block_start, margin_block_end) = match (block_start, block_end) { (MaybeAuto::Auto, MaybeAuto::Auto) => { @@ -249,50 +306,81 @@ impl BSizeConstraintSolution { let margin_block_end = block_end_margin.specified_or_zero(); // Use a dummy value for `block_start`, since it has the static position. (Au(0), block_size, margin_block_start, margin_block_end) - } + }, (MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end)) => { match (block_start_margin, block_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { - let total_margin_val = available_block_size - block_start - block_end - - block_size; - (block_start, - block_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) - } + let total_margin_val = + available_block_size - block_start - block_end - block_size; + ( + block_start, + block_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) + }, (MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => { let sum = block_start + block_end + block_size + margin_block_start; - (block_start, - block_size, - margin_block_start, - available_block_size - sum) - } + ( + block_start, + block_size, + margin_block_start, + available_block_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => { let sum = block_start + block_end + block_size + margin_block_end; - (block_start, block_size, available_block_size - sum, margin_block_end) - } - (MaybeAuto::Specified(margin_block_start), - MaybeAuto::Specified(margin_block_end)) => { + ( + block_start, + block_size, + available_block_size - sum, + margin_block_end, + ) + }, + ( + MaybeAuto::Specified(margin_block_start), + MaybeAuto::Specified(margin_block_end), + ) => { // Values are over-constrained. Ignore value for 'block-end'. - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, } - } + }, // If only one is Auto, solve for it (MaybeAuto::Auto, MaybeAuto::Specified(block_end)) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); let sum = block_end + block_size + margin_block_start + margin_block_end; - (available_block_size - sum, block_size, margin_block_start, margin_block_end) - } + ( + available_block_size - sum, + block_size, + margin_block_start, + margin_block_end, + ) + }, (MaybeAuto::Specified(block_start), MaybeAuto::Auto) => { let margin_block_start = block_start_margin.specified_or_zero(); let margin_block_end = block_end_margin.specified_or_zero(); - (block_start, block_size, margin_block_start, margin_block_end) - } + ( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) + }, }; - BSizeConstraintSolution::new(block_start, block_size, margin_block_start, margin_block_end) + BSizeConstraintSolution::new( + block_start, + block_size, + margin_block_start, + margin_block_end, + ) } } @@ -314,21 +402,26 @@ impl CandidateBSizeIterator { /// Creates a new candidate block-size iterator. `block_container_block-size` is `None` if the block-size /// of the block container has not been determined yet. It will always be `Some` in the case of /// absolutely-positioned containing blocks. - pub fn new(fragment: &Fragment, block_container_block_size: Option<Au>) - -> CandidateBSizeIterator { + pub fn new( + fragment: &Fragment, + block_container_block_size: Option<Au>, + ) -> CandidateBSizeIterator { // Per CSS 2.1 § 10.7, (assuming an horizontal writing mode,) // percentages in `min-height` and `max-height` refer to the height of // the containing block. // If that is not determined yet by the time we need to resolve // `min-height` and `max-height`, percentage values are ignored. - let block_size = match (fragment.style.content_block_size(), block_container_block_size) { + let block_size = match ( + fragment.style.content_block_size(), + block_container_block_size, + ) { (LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => { MaybeAuto::Specified(block_container_block_size.scale_by(percent.0)) - } + }, (LengthOrPercentageOrAuto::Calc(calc), _) => { MaybeAuto::from_option(calc.to_used_value(block_container_block_size)) - } + }, (LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto, (LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(Au::from(length)), @@ -336,10 +429,10 @@ impl CandidateBSizeIterator { let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) { (LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => { Some(block_container_block_size.scale_by(percent.0)) - } + }, (LengthOrPercentageOrNone::Calc(calc), _) => { calc.to_used_value(block_container_block_size) - } + }, (LengthOrPercentageOrNone::Percentage(_), None) | (LengthOrPercentageOrNone::None, _) => None, (LengthOrPercentageOrNone::Length(length), _) => Some(Au::from(length)), @@ -347,10 +440,10 @@ impl CandidateBSizeIterator { let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) { (LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => { block_container_block_size.scale_by(percent.0) - } - (LengthOrPercentage::Calc(calc), _) => { - calc.to_used_value(block_container_block_size).unwrap_or(Au(0)) - } + }, + (LengthOrPercentage::Calc(calc), _) => calc + .to_used_value(block_container_block_size) + .unwrap_or(Au(0)), (LengthOrPercentage::Percentage(_), None) => Au(0), (LengthOrPercentage::Length(length), _) => Au::from(length), }; @@ -380,37 +473,35 @@ impl Iterator for CandidateBSizeIterator { fn next(&mut self) -> Option<MaybeAuto> { self.status = match self.status { CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying, - CandidateBSizeIteratorStatus::Trying => { - match self.max_block_size { - Some(max_block_size) if self.candidate_value > max_block_size => { - CandidateBSizeIteratorStatus::TryingMax - } - _ if self.candidate_value < self.min_block_size => { - CandidateBSizeIteratorStatus::TryingMin - } - _ => CandidateBSizeIteratorStatus::Found, - } - } + CandidateBSizeIteratorStatus::Trying => match self.max_block_size { + Some(max_block_size) if self.candidate_value > max_block_size => { + CandidateBSizeIteratorStatus::TryingMax + }, + _ if self.candidate_value < self.min_block_size => { + CandidateBSizeIteratorStatus::TryingMin + }, + _ => CandidateBSizeIteratorStatus::Found, + }, CandidateBSizeIteratorStatus::TryingMax => { if self.candidate_value < self.min_block_size { CandidateBSizeIteratorStatus::TryingMin } else { CandidateBSizeIteratorStatus::Found } - } + }, CandidateBSizeIteratorStatus::TryingMin | CandidateBSizeIteratorStatus::Found => { CandidateBSizeIteratorStatus::Found - } + }, }; match self.status { CandidateBSizeIteratorStatus::Trying => Some(self.block_size), CandidateBSizeIteratorStatus::TryingMax => { Some(MaybeAuto::Specified(self.max_block_size.unwrap())) - } + }, CandidateBSizeIteratorStatus::TryingMin => { Some(MaybeAuto::Specified(self.min_block_size)) - } + }, CandidateBSizeIteratorStatus::Found => None, CandidateBSizeIteratorStatus::Initial => panic!(), } @@ -451,17 +542,25 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> { #[inline] fn process(&self, flow: &mut Flow) { if !flow.is_block_like() { - return + return; } // This flow might not be an absolutely positioned flow if it is the root of the tree. let block = flow.as_mut_block(); - if !block.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if !block + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { return; } - if !block.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { - return + if !block + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { + return; } block.calculate_absolute_block_size_and_margins(self.0); @@ -533,14 +632,20 @@ impl BlockFlow { BlockFlow::from_fragment_and_float_kind(fragment, None) } - pub fn from_fragment_and_float_kind(fragment: Fragment, float_kind: Option<FloatKind>) - -> BlockFlow { + pub fn from_fragment_and_float_kind( + fragment: Fragment, + float_kind: Option<FloatKind>, + ) -> BlockFlow { let writing_mode = fragment.style().writing_mode; BlockFlow { - base: BaseFlow::new(Some(fragment.style()), writing_mode, match float_kind { - Some(_) => ForceNonfloatedFlag::FloatIfNecessary, - None => ForceNonfloatedFlag::ForceNonfloated, - }), + base: BaseFlow::new( + Some(fragment.style()), + writing_mode, + match float_kind { + Some(_) => ForceNonfloatedFlag::FloatIfNecessary, + None => ForceNonfloatedFlag::ForceNonfloated, + }, + ), fragment: fragment, float: float_kind.map(|kind| Box::new(FloatedBlockInfo::new(kind))), flags: BlockFlowFlags::empty(), @@ -552,7 +657,11 @@ impl BlockFlow { /// This determines the algorithm used to calculate inline-size, block-size, and the /// relevant margins for this Block. pub fn block_type(&self) -> BlockType { - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { if self.fragment.is_replaced() { BlockType::AbsoluteReplaced } else { @@ -582,65 +691,85 @@ impl BlockFlow { } /// Compute the actual inline size and position for this block. - pub fn compute_used_inline_size(&mut self, - shared_context: &SharedStyleContext, - containing_block_inline_size: Au) { + pub fn compute_used_inline_size( + &mut self, + shared_context: &SharedStyleContext, + containing_block_inline_size: Au, + ) { let block_type = self.block_type(); match block_type { BlockType::AbsoluteReplaced => { let inline_size_computer = AbsoluteReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::AbsoluteNonReplaced => { let inline_size_computer = AbsoluteNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::FloatReplaced => { let inline_size_computer = FloatReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::FloatNonReplaced => { let inline_size_computer = FloatNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::InlineBlockReplaced => { let inline_size_computer = InlineBlockReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::InlineBlockNonReplaced => { let inline_size_computer = InlineBlockNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::Replaced => { let inline_size_computer = BlockReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::NonReplaced => { let inline_size_computer = BlockNonReplaced; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, BlockType::InlineFlexItem => { let inline_size_computer = InlineFlexItem; - inline_size_computer.compute_used_inline_size(self, - shared_context, - containing_block_inline_size); - } + inline_size_computer.compute_used_inline_size( + self, + shared_context, + containing_block_inline_size, + ); + }, } } @@ -652,9 +781,15 @@ impl BlockFlow { pub fn stacking_relative_border_box(&self, coor: CoordinateSystem) -> Rect<Au> { return self.fragment.stacking_relative_border_box( &self.base.stacking_relative_position, - &self.base.early_absolute_position_info.relative_containing_block_size, - self.base.early_absolute_position_info.relative_containing_block_mode, - coor); + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + self.base + .early_absolute_position_info + .relative_containing_block_mode, + coor, + ); } /// Return the size of the containing block for the given immediate absolute descendant of this @@ -663,14 +798,23 @@ impl BlockFlow { /// Right now, this only gets the containing block size for absolutely positioned elements. /// Note: We assume this is called in a top-down traversal, so it is ok to reference the CB. #[inline] - pub fn containing_block_size(&self, viewport_size: &Size2D<Au>, descendant: OpaqueFlow) - -> LogicalSize<Au> { - debug_assert!(self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)); + pub fn containing_block_size( + &self, + viewport_size: &Size2D<Au>, + descendant: OpaqueFlow, + ) -> LogicalSize<Au> { + debug_assert!( + self.base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + ); if self.is_fixed() || self.is_root() { // Initial containing block is the CB for the root LogicalSize::from_physical(self.base.writing_mode, *viewport_size) } else { - self.base.absolute_cb.generated_containing_block_size(descendant) + self.base + .absolute_cb + .generated_containing_block_size(descendant) } } @@ -680,8 +824,13 @@ impl BlockFlow { /// calculated in the bubble-inline-sizes traversal. pub fn get_shrink_to_fit_inline_size(&self, available_inline_size: Au) -> Au { let content_intrinsic_inline_sizes = self.content_intrinsic_inline_sizes(); - min(content_intrinsic_inline_sizes.preferred_inline_size, - max(content_intrinsic_inline_sizes.minimum_inline_size, available_inline_size)) + min( + content_intrinsic_inline_sizes.preferred_inline_size, + max( + content_intrinsic_inline_sizes.minimum_inline_size, + available_inline_size, + ), + ) } /// If this is the root flow, shifts all kids down and adjusts our size to account for @@ -689,22 +838,24 @@ impl BlockFlow { /// /// TODO(#2017, pcwalton): This is somewhat inefficient (traverses kids twice); can we do /// better? - fn adjust_fragments_for_collapsed_margins_if_root(&mut self, - shared_context: &SharedStyleContext) { + fn adjust_fragments_for_collapsed_margins_if_root( + &mut self, + shared_context: &SharedStyleContext, + ) { if !self.is_root() { - return + return; } - let (block_start_margin_value, block_end_margin_value) = - match self.base.collapsible_margins { - CollapsibleMargins::CollapseThrough(_) => { - panic!("Margins unexpectedly collapsed through root flow.") - } - CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { - (block_start_margin.collapse(), block_end_margin.collapse()) - } - CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), - }; + let (block_start_margin_value, block_end_margin_value) = match self.base.collapsible_margins + { + CollapsibleMargins::CollapseThrough(_) => { + panic!("Margins unexpectedly collapsed through root flow.") + }, + CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { + (block_start_margin.collapse(), block_end_margin.collapse()) + }, + CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), + }; // Shift all kids down (or up, if margins are negative) if necessary. if block_start_margin_value != Au(0) { @@ -718,12 +869,14 @@ impl BlockFlow { // is not correct behavior according to CSS 2.1 § 10.5. Instead I think we should treat the // root element as having `overflow: scroll` and use the layers-based scrolling // infrastructure to make it scrollable. - let viewport_size = - LogicalSize::from_physical(self.fragment.style.writing_mode, - shared_context.viewport_size()); - let block_size = max(viewport_size.block, - self.fragment.border_box.size.block + block_start_margin_value + - block_end_margin_value); + let viewport_size = LogicalSize::from_physical( + self.fragment.style.writing_mode, + shared_context.viewport_size(), + ); + let block_size = max( + viewport_size.block, + self.fragment.border_box.size.block + block_start_margin_value + block_end_margin_value, + ); self.base.position.size.block = block_size; self.fragment.border_box.size.block = block_size; @@ -774,69 +927,95 @@ impl BlockFlow { /// `inline(always)` because this is only ever called by in-order or non-in-order top-level /// methods. #[inline(always)] - pub fn assign_block_size_block_base(&mut self, - layout_context: &LayoutContext, - mut fragmentation_context: Option<FragmentationContext>, - margins_may_collapse: MarginsMayCollapseFlag) - -> Option<Arc<Flow>> { - let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", - self.base.debug_id()); + pub fn assign_block_size_block_base( + &mut self, + layout_context: &LayoutContext, + mut fragmentation_context: Option<FragmentationContext>, + margins_may_collapse: MarginsMayCollapseFlag, + ) -> Option<Arc<Flow>> { + let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", self.base.debug_id()); let mut break_at = None; let content_box = self.fragment.content_box(); - if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) { + if self + .base + .restyle_damage + .contains(ServoRestyleDamage::REFLOW) + { // Our current border-box position. let mut cur_b = Au(0); // Absolute positioning establishes a block formatting context. Don't propagate floats // in or out. (But do propagate them between kids.) - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || - margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || + margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse + { self.base.floats = Floats::new(self.fragment.style.writing_mode); } let writing_mode = self.base.floats.writing_mode; self.base.floats.translate(LogicalSize::new( - writing_mode, -self.fragment.inline_start_offset(), Au(0))); + writing_mode, + -self.fragment.inline_start_offset(), + Au(0), + )); // The sum of our block-start border and block-start padding. let block_start_offset = self.fragment.border_padding.block_start; translate_including_floats(&mut cur_b, block_start_offset, &mut self.base.floats); - let can_collapse_block_start_margin_with_kids = - margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse && - !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + let can_collapse_block_start_margin_with_kids = margins_may_collapse == + MarginsMayCollapseFlag::MarginsMayCollapse && + !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && self.fragment.border_padding.block_start == Au(0); let mut margin_collapse_info = MarginCollapseInfo::initialize_block_start_margin( &self.fragment, - can_collapse_block_start_margin_with_kids); + can_collapse_block_start_margin_with_kids, + ); // At this point, `cur_b` is at the content edge of our box. Now iterate over children. let mut floats = self.base.floats.clone(); let thread_id = self.base.thread_id; let (mut had_floated_children, mut had_children_with_clearance) = (false, false); for (child_index, kid) in self.base.child_iter_mut().enumerate() { - if kid.base().flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if kid + .base() + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // Assume that the *hypothetical box* for an absolute flow starts immediately // after the margin-end border edge of the previous flow. - if kid.base().flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if kid + .base() + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { let previous_bottom_margin = margin_collapse_info.current_float_ceiling(); kid.mut_base().position.start.b = cur_b + - kid.base().collapsible_margins - .block_start_margin_for_noncollapsible_context() + + kid.base() + .collapsible_margins + .block_start_margin_for_noncollapsible_context() + previous_bottom_margin } kid.place_float_if_applicable(); if !kid.base().flags.is_float() { - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); + kid.assign_block_size_for_inorder_child_if_necessary( + layout_context, + thread_id, + content_box, + ); } // Skip the collapsing and float processing for absolute flow kids and continue // with the next flow. - continue + continue; } let previous_b = cur_b; @@ -865,7 +1044,7 @@ impl BlockFlow { let kid_base = kid.mut_base(); floats = kid_base.floats.clone(); - continue + continue; } // If we have clearance, assume there are no floats in. @@ -880,22 +1059,26 @@ impl BlockFlow { } // Lay the child out if this was an in-order traversal. - let need_to_process_child_floats = - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); + let need_to_process_child_floats = kid + .assign_block_size_for_inorder_child_if_necessary( + layout_context, + thread_id, + content_box, + ); if !had_children_with_clearance && - floats.is_present() && - (kid.base().flags.contains(FlowFlags::CLEARS_LEFT) || - kid.base().flags.contains(FlowFlags::CLEARS_RIGHT)) { + floats.is_present() && + (kid.base().flags.contains(FlowFlags::CLEARS_LEFT) || + kid.base().flags.contains(FlowFlags::CLEARS_RIGHT)) + { had_children_with_clearance = true } // Handle any (possibly collapsed) top margin. let delta = margin_collapse_info.advance_block_start_margin( &kid.base().collapsible_margins, - !had_children_with_clearance); + !had_children_with_clearance, + ); translate_including_floats(&mut cur_b, delta, &mut floats); // Collapse-through margins should be placed at the top edge, @@ -905,8 +1088,10 @@ impl BlockFlow { } // Clear past the floats that came in, if necessary. - let clearance = match (kid.base().flags.contains(FlowFlags::CLEARS_LEFT), - kid.base().flags.contains(FlowFlags::CLEARS_RIGHT)) { + let clearance = match ( + kid.base().flags.contains(FlowFlags::CLEARS_LEFT), + kid.base().flags.contains(FlowFlags::CLEARS_RIGHT), + ) { (false, false) => Au(0), (true, false) => floats.clearance(ClearType::Left), (false, true) => floats.clearance(ClearType::Right), @@ -942,19 +1127,19 @@ impl BlockFlow { cur_b = cur_b + delta; kid_base.position.start.b = kid_base.position.start.b + delta; delta - } - _ => Au(0) + }, + _ => Au(0), }; if break_at.is_some() { - break + break; } if let Some(ref mut ctx) = fragmentation_context { if cur_b > ctx.available_block_size && !ctx.this_fragment_is_empty { break_at = Some((child_index, None)); cur_b = previous_b; - break + break; } ctx.this_fragment_is_empty = false } @@ -965,38 +1150,50 @@ impl BlockFlow { } // Add in our block-end margin and compute our collapsible margins. - let can_collapse_block_end_margin_with_kids = - margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse && - !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + let can_collapse_block_end_margin_with_kids = margins_may_collapse == + MarginsMayCollapseFlag::MarginsMayCollapse && + !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && self.fragment.border_padding.block_end == Au(0); - let (collapsible_margins, delta) = - margin_collapse_info.finish_and_compute_collapsible_margins( - &self.fragment, - self.base.block_container_explicit_block_size, - can_collapse_block_end_margin_with_kids, - !had_floated_children); + let (collapsible_margins, delta) = margin_collapse_info + .finish_and_compute_collapsible_margins( + &self.fragment, + self.base.block_container_explicit_block_size, + can_collapse_block_end_margin_with_kids, + !had_floated_children, + ); self.base.collapsible_margins = collapsible_margins; translate_including_floats(&mut cur_b, delta, &mut floats); let mut block_size = cur_b - block_start_offset; let is_root = self.is_root(); - if is_root || self.formatting_context_type() != FormattingContextType::None || - self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if is_root || self.formatting_context_type() != FormattingContextType::None || self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest // way to handle this is to just treat it as clearance. block_size = block_size + floats.clearance(ClearType::Both); } - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { // FIXME(#2003, pcwalton): The max is taken here so that you can scroll the page, // but this is not correct behavior according to CSS 2.1 § 10.5. Instead I think we // should treat the root element as having `overflow: scroll` and use the layers- // based scrolling infrastructure to make it scrollable. if is_root { - let viewport_size = - LogicalSize::from_physical(self.fragment.style.writing_mode, - layout_context.shared_context().viewport_size()); + let viewport_size = LogicalSize::from_physical( + self.fragment.style.writing_mode, + layout_context.shared_context().viewport_size(), + ); block_size = max(viewport_size.block, block_size) } @@ -1007,23 +1204,26 @@ impl BlockFlow { self.fragment.border_box.size.block = block_size; } - - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { self.propagate_early_absolute_position_info_to_children(); - return None + return None; } // Compute any explicitly-specified block size. // Can't use `for` because we assign to `candidate_block_size_iterator.candidate_value`. let mut candidate_block_size_iterator = CandidateBSizeIterator::new( &self.fragment, - self.base.block_container_explicit_block_size); + self.base.block_container_explicit_block_size, + ); while let Some(candidate_block_size) = candidate_block_size_iterator.next() { - candidate_block_size_iterator.candidate_value = - match candidate_block_size { - MaybeAuto::Auto => block_size, - MaybeAuto::Specified(value) => value - } + candidate_block_size_iterator.candidate_value = match candidate_block_size { + MaybeAuto::Auto => block_size, + MaybeAuto::Specified(value) => value, + } } // Adjust `cur_b` as necessary to account for the explicitly-specified block-size. @@ -1046,9 +1246,11 @@ impl BlockFlow { // Translate the current set of floats back into the parent coordinate system in the // inline direction, and store them in the flow so that flows that come later in the // document can access them. - floats.translate(LogicalSize::new(writing_mode, - self.fragment.inline_start_offset(), - Au(0))); + floats.translate(LogicalSize::new( + writing_mode, + self.fragment.inline_start_offset(), + Au(0), + )); self.base.floats = floats.clone(); self.adjust_fragments_for_collapsed_margins_if_root(layout_context.shared_context()); } else { @@ -1056,9 +1258,11 @@ impl BlockFlow { // necessary. let thread_id = self.base.thread_id; for kid in self.base.child_iter_mut() { - kid.assign_block_size_for_inorder_child_if_necessary(layout_context, - thread_id, - content_box); + kid.assign_block_size_for_inorder_child_if_necessary( + layout_context, + thread_id, + content_box, + ); } } @@ -1075,10 +1279,18 @@ impl BlockFlow { // Also don't remove the dirty bits if we're a block formatting context since our inline // size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.) if (self.base.flags.is_float() || - self.formatting_context_type() == FormattingContextType::None) && - !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.formatting_context_type() == FormattingContextType::None) && + !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } break_at.and_then(|(i, child_remaining)| { @@ -1116,15 +1328,18 @@ impl BlockFlow { // Our `position` field accounts for positive margins, but not negative margins. (See // calculation of `extra_inline_size_from_margin` below.) Negative margins must be taken // into account for float placement, however. So we add them in here. - let inline_size_for_float_placement = self.base.position.size.inline + - min(Au(0), self.fragment.margin.inline_start_end()); + let inline_size_for_float_placement = + self.base.position.size.inline + min(Au(0), self.fragment.margin.inline_start_end()); let info = PlacementInfo { size: LogicalSize::new( self.fragment.style.writing_mode, inline_size_for_float_placement, - block_size + self.fragment.margin.block_start_end()) - .convert(self.fragment.style.writing_mode, self.base.floats.writing_mode), + block_size + self.fragment.margin.block_start_end(), + ).convert( + self.fragment.style.writing_mode, + self.base.floats.writing_mode, + ), ceiling: clearance + float_info.float_ceiling, max_inline_size: float_info.containing_inline_size, kind: float_info.float_kind, @@ -1139,32 +1354,51 @@ impl BlockFlow { // Move in from the margin edge, as per CSS 2.1 § 9.5, floats may not overlap anything on // their margin edges. - let float_offset = self.base.floats.last_float_pos().unwrap() - .convert(self.base.floats.writing_mode, - self.base.writing_mode, - container_size) - .start; - let margin_offset = LogicalPoint::new(self.base.writing_mode, - Au(0), - self.fragment.margin.block_start); - - let mut origin = LogicalPoint::new(self.base.writing_mode, - self.base.position.start.i, - self.base.position.start.b); + let float_offset = self + .base + .floats + .last_float_pos() + .unwrap() + .convert( + self.base.floats.writing_mode, + self.base.writing_mode, + container_size, + ).start; + let margin_offset = LogicalPoint::new( + self.base.writing_mode, + Au(0), + self.fragment.margin.block_start, + ); + + let mut origin = LogicalPoint::new( + self.base.writing_mode, + self.base.position.start.i, + self.base.position.start.b, + ); origin = origin.add_point(&float_offset).add_point(&margin_offset); - self.base.position = LogicalRect::from_point_size(self.base.writing_mode, - origin, - self.base.position.size); + self.base.position = + LogicalRect::from_point_size(self.base.writing_mode, origin, self.base.position.size); } - pub fn explicit_block_containing_size(&self, shared_context: &SharedStyleContext) -> Option<Au> { + pub fn explicit_block_containing_size( + &self, + shared_context: &SharedStyleContext, + ) -> Option<Au> { if self.is_root() || self.is_fixed() { - let viewport_size = LogicalSize::from_physical(self.fragment.style.writing_mode, - shared_context.viewport_size()); + let viewport_size = LogicalSize::from_physical( + self.fragment.style.writing_mode, + shared_context.viewport_size(), + ); Some(viewport_size.block) - } else if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && - self.base.block_container_explicit_block_size.is_none() { - self.base.absolute_cb.explicit_block_containing_size(shared_context) + } else if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + self.base.block_container_explicit_block_size.is_none() + { + self.base + .absolute_cb + .explicit_block_containing_size(shared_context) } else { self.base.block_container_explicit_block_size } @@ -1174,58 +1408,56 @@ impl BlockFlow { let content_block_size = self.fragment.style().content_block_size(); match (content_block_size, containing_block_size) { - (LengthOrPercentageOrAuto::Calc(calc), _) => { - calc.to_used_value(containing_block_size) - } + (LengthOrPercentageOrAuto::Calc(calc), _) => calc.to_used_value(containing_block_size), (LengthOrPercentageOrAuto::Length(length), _) => Some(Au::from(length)), (LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => { Some(container_size.scale_by(percent.0)) - } + }, (LengthOrPercentageOrAuto::Percentage(_), None) | - (LengthOrPercentageOrAuto::Auto, None) => { - None - } + (LengthOrPercentageOrAuto::Auto, None) => None, (LengthOrPercentageOrAuto::Auto, Some(container_size)) => { let (block_start, block_end) = { let position = self.fragment.style().logical_position(); - (MaybeAuto::from_style(position.block_start, container_size), - MaybeAuto::from_style(position.block_end, container_size)) + ( + MaybeAuto::from_style(position.block_start, container_size), + MaybeAuto::from_style(position.block_end, container_size), + ) }; match (block_start, block_end) { (MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end)) => { - let available_block_size = container_size - self.fragment.border_padding.block_start_end(); + let available_block_size = + container_size - self.fragment.border_padding.block_start_end(); // Non-auto margin-block-start and margin-block-end values have already been // calculated during assign-inline-size. let margin = self.fragment.style().logical_margin(); let margin_block_start = match margin.block_start { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_start) + _ => MaybeAuto::Specified(self.fragment.margin.block_start), }; let margin_block_end = match margin.block_end { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_end) + _ => MaybeAuto::Specified(self.fragment.margin.block_end), }; let margin_block_start = margin_block_start.specified_or_zero(); let margin_block_end = margin_block_end.specified_or_zero(); let sum = block_start + block_end + margin_block_start + margin_block_end; Some(available_block_size - sum) - } + }, - (_, _) => { - None - } + (_, _) => None, } - } + }, } } fn calculate_absolute_block_size_and_margins(&mut self, shared_context: &SharedStyleContext) { let opaque_self = OpaqueFlow::from_flow(self); - let containing_block_block_size = - self.containing_block_size(&shared_context.viewport_size(), opaque_self).block; + let containing_block_block_size = self + .containing_block_size(&shared_context.viewport_size(), opaque_self) + .block; // This is the stored content block-size value from assign-block-size let content_block_size = self.fragment.border_box.size.block; @@ -1237,24 +1469,24 @@ impl BlockFlow { let margin = self.fragment.style().logical_margin(); let margin_block_start = match margin.block_start { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_start) + _ => MaybeAuto::Specified(self.fragment.margin.block_start), }; let margin_block_end = match margin.block_end { LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto, - _ => MaybeAuto::Specified(self.fragment.margin.block_end) + _ => MaybeAuto::Specified(self.fragment.margin.block_end), }; let block_start; let block_end; { let position = self.fragment.style().logical_position(); - block_start = MaybeAuto::from_style(position.block_start, - containing_block_block_size); + block_start = + MaybeAuto::from_style(position.block_start, containing_block_block_size); block_end = MaybeAuto::from_style(position.block_end, containing_block_block_size); } - let available_block_size = containing_block_block_size - - self.fragment.border_padding.block_start_end(); + let available_block_size = + containing_block_block_size - self.fragment.border_padding.block_start_end(); if self.fragment.is_replaced() { // Calculate used value of block-size just like we do for inline replaced elements. // TODO: Pass in the containing block block-size when Fragment's @@ -1265,21 +1497,24 @@ impl BlockFlow { // Check this when that has been fixed. let block_size_used_val = self.fragment.border_box.size.block - self.fragment.border_padding.block_start_end(); - solution = Some(BSizeConstraintSolution::solve_vertical_constraints_abs_replaced( + solution = Some( + BSizeConstraintSolution::solve_vertical_constraints_abs_replaced( block_size_used_val, margin_block_start, margin_block_end, block_start, block_end, content_block_size, - available_block_size)) + available_block_size, + ), + ) } else { let mut candidate_block_size_iterator = CandidateBSizeIterator::new(&self.fragment, Some(containing_block_block_size)); // Can't use `for` because we assign to // `candidate_block_size_iterator.candidate_value`. - while let Some(block_size_used_val) = candidate_block_size_iterator.next() { + while let Some(block_size_used_val) = candidate_block_size_iterator.next() { solution = Some( BSizeConstraintSolution::solve_vertical_constraints_abs_nonreplaced( block_size_used_val, @@ -1288,10 +1523,11 @@ impl BlockFlow { block_start, block_end, content_block_size, - available_block_size)); + available_block_size, + ), + ); - candidate_block_size_iterator.candidate_value = - solution.unwrap().block_size; + candidate_block_size_iterator.candidate_value = solution.unwrap().block_size; } } } @@ -1301,7 +1537,11 @@ impl BlockFlow { self.fragment.margin.block_end = solution.margin_block_end; self.fragment.border_box.start.b = Au(0); - if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { self.base.position.start.b = solution.block_start + self.fragment.margin.block_start } @@ -1310,8 +1550,12 @@ impl BlockFlow { self.fragment.border_box.size.block = block_size; self.base.position.size.block = block_size; - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } /// Compute inline size based using the `block_container_inline_size` set by the parent flow. @@ -1332,18 +1576,16 @@ impl BlockFlow { /// `#[inline(always)]` because this is called only from block or table inline-size assignment /// and the code for block layout is significantly simpler. #[inline(always)] - pub fn propagate_assigned_inline_size_to_children<F>(&mut self, - shared_context: &SharedStyleContext, - inline_start_content_edge: Au, - inline_end_content_edge: Au, - content_inline_size: Au, - mut callback: F) - where F: FnMut(&mut Flow, - usize, - Au, - WritingMode, - &mut Au, - &mut Au) { + pub fn propagate_assigned_inline_size_to_children<F>( + &mut self, + shared_context: &SharedStyleContext, + inline_start_content_edge: Au, + inline_end_content_edge: Au, + content_inline_size: Au, + mut callback: F, + ) where + F: FnMut(&mut Flow, usize, Au, WritingMode, &mut Au, &mut Au), + { let flags = self.base.flags.clone(); let opaque_self = OpaqueFlow::from_flow(self); @@ -1355,13 +1597,20 @@ impl BlockFlow { }; let parent_container_size = self.explicit_block_containing_size(shared_context); // https://drafts.csswg.org/css-ui-3/#box-sizing - let mut explicit_content_size = self - .explicit_block_size(parent_container_size) - .map(|x| if x < box_border { Au(0) } else { x - box_border }); - if self.is_root() { explicit_content_size = max(parent_container_size, explicit_content_size); } + let mut explicit_content_size = self.explicit_block_size(parent_container_size).map(|x| { + if x < box_border { + Au(0) + } else { + x - box_border + } + }); + if self.is_root() { + explicit_content_size = max(parent_container_size, explicit_content_size); + } // Calculate containing block inline size. let containing_block_size = if flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { - self.containing_block_size(&shared_context.viewport_size(), opaque_self).inline + self.containing_block_size(&shared_context.viewport_size(), opaque_self) + .inline } else { content_inline_size }; @@ -1388,13 +1637,17 @@ impl BlockFlow { // float child does not have `REFLOW` set, we must be careful to avoid touching its // inline position, as no logic will run afterward to set its true value. let kid_base = kid.mut_base(); - let reflow_damage = if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + let reflow_damage = if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { ServoRestyleDamage::REFLOW_OUT_OF_FLOW } else { ServoRestyleDamage::REFLOW }; - if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) && - kid_base.restyle_damage.contains(reflow_damage) { + if kid_base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) && + kid_base.restyle_damage.contains(reflow_damage) + { kid_base.position.start.i = if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() { inline_start_content_edge @@ -1409,26 +1662,33 @@ impl BlockFlow { // Call the callback to propagate extra inline size information down to the child. This // is currently used for tables. - callback(kid, - i, - content_inline_size, - containing_block_mode, - &mut inline_start_margin_edge, - &mut inline_end_margin_edge); + callback( + kid, + i, + content_inline_size, + containing_block_mode, + &mut inline_start_margin_edge, + &mut inline_end_margin_edge, + ); // Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow. // // TODO(#2265, pcwalton): Do this in the cascade instead. let containing_block_text_align = self.fragment.style().get_inherited_text().text_align; - kid.mut_base().flags.set_text_align(containing_block_text_align); + kid.mut_base() + .flags + .set_text_align(containing_block_text_align); // Handle `text-indent` on behalf of any inline children that we have. This is // necessary because any percentages are relative to the containing block, which only // we know. if kid.is_inline_flow() { - kid.as_mut_inline().first_line_indentation = - self.fragment.style().get_inherited_text().text_indent - .to_used_value(containing_block_size); + kid.as_mut_inline().first_line_indentation = self + .fragment + .style() + .get_inherited_text() + .text_indent + .to_used_value(containing_block_size); } } } @@ -1437,11 +1697,11 @@ impl BlockFlow { /// `FormattingContextType`. pub fn formatting_context_type(&self) -> FormattingContextType { if self.is_inline_flex_item() || self.is_block_flex_item() { - return FormattingContextType::Other + return FormattingContextType::Other; } let style = self.fragment.style(); if style.get_box().float != Float::None { - return FormattingContextType::Other + return FormattingContextType::Other; } match style.get_box().display { Display::TableCell | @@ -1449,14 +1709,13 @@ impl BlockFlow { Display::TableRowGroup | Display::Table | Display::InlineBlock | - Display::Flex => { - FormattingContextType::Other - } + Display::Flex => FormattingContextType::Other, _ if style.get_box().overflow_x != StyleOverflow::Visible || - style.get_box().overflow_y != StyleOverflow::Visible || - style.is_multicol() => { + style.get_box().overflow_y != StyleOverflow::Visible || + style.is_multicol() => + { FormattingContextType::Block - } + }, _ => FormattingContextType::None, } } @@ -1472,18 +1731,28 @@ impl BlockFlow { /// on the floats we could see at the time of inline-size assignment. The job of this function, /// therefore, is not only to assign the final size but also to perform the layout again for /// this block formatting context if our speculation was wrong. - fn assign_inline_position_for_formatting_context(&mut self, - layout_context: &LayoutContext, - content_box: LogicalRect<Au>) { + fn assign_inline_position_for_formatting_context( + &mut self, + layout_context: &LayoutContext, + content_box: LogicalRect<Au>, + ) { debug_assert_ne!(self.formatting_context_type(), FormattingContextType::None); - if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { - return + if !self + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { + return; } // We do this first to avoid recomputing our inline size when we propagate it. - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); // The code below would completely wreck the layout if run on a flex item, however: // * Flex items are always the children of flex containers. @@ -1494,16 +1763,18 @@ impl BlockFlow { // Therefore, a flex item cannot be impacted by a float. // See also: https://www.w3.org/TR/css-flexbox-1/#flex-containers if !self.base.might_have_floats_in() { - return + return; } // If you remove the might_have_floats_in conditional, this will go off. debug_assert!(!self.is_inline_flex_item()); // Compute the available space for us, based on the actual floats. - let rect = self.base.floats.available_rect(Au(0), - self.fragment.border_box.size.block, - content_box.size.inline); + let rect = self.base.floats.available_rect( + Au(0), + self.fragment.border_box.size.block, + content_box.size.inline, + ); let available_inline_size = if let Some(rect) = rect { // Offset our position by whatever displacement is needed to not impact the floats. // Also, account for margins sliding behind floats. @@ -1525,25 +1796,29 @@ impl BlockFlow { } else { content_box.size.inline } - self.fragment.margin.inline_start_end(); - let max_inline_size = - self.fragment.style().max_inline_size() - .to_used_value(self.base.block_container_inline_size) - .unwrap_or(MAX_AU); - let min_inline_size = - self.fragment.style().min_inline_size().to_used_value(self.base.block_container_inline_size); + let max_inline_size = self + .fragment + .style() + .max_inline_size() + .to_used_value(self.base.block_container_inline_size) + .unwrap_or(MAX_AU); + let min_inline_size = self + .fragment + .style() + .min_inline_size() + .to_used_value(self.base.block_container_inline_size); let specified_inline_size = self.fragment.style().content_inline_size(); let container_size = self.base.block_container_inline_size; - let inline_size = - if let MaybeAuto::Specified(size) = MaybeAuto::from_style(specified_inline_size, - container_size) { - match self.fragment.style().get_position().box_sizing { - BoxSizing::BorderBox => size, - BoxSizing::ContentBox => - size + self.fragment.border_padding.inline_start_end(), - } - } else { - max(min_inline_size, min(available_inline_size, max_inline_size)) - }; + let inline_size = if let MaybeAuto::Specified(size) = + MaybeAuto::from_style(specified_inline_size, container_size) + { + match self.fragment.style().get_position().box_sizing { + BoxSizing::BorderBox => size, + BoxSizing::ContentBox => size + self.fragment.border_padding.inline_start_end(), + } + } else { + max(min_inline_size, min(available_inline_size, max_inline_size)) + }; self.base.position.size.inline = inline_size + self.fragment.margin.inline_start_end(); // If float speculation failed, fixup our layout, and re-layout all the children. @@ -1563,12 +1838,15 @@ impl BlockFlow { self.assign_block_size(layout_context); } - debug_assert_eq!(self.fragment.margin_box_inline_size(), self.base.position.size.inline); + debug_assert_eq!( + self.fragment.margin_box_inline_size(), + self.base.position.size.inline + ); } fn is_inline_block_or_inline_flex(&self) -> bool { self.fragment.style().get_box().display == Display::InlineBlock || - self.fragment.style().get_box().display == Display::InlineFlex + self.fragment.style().get_box().display == Display::InlineFlex } /// Computes the content portion (only) of the intrinsic inline sizes of this flow. This is @@ -1578,9 +1856,11 @@ impl BlockFlow { let (border_padding, margin) = self.fragment.surrounding_intrinsic_inline_size(); IntrinsicISizes { minimum_inline_size: self.base.intrinsic_inline_sizes.minimum_inline_size - - border_padding - margin, + border_padding - + margin, preferred_inline_size: self.base.intrinsic_inline_sizes.preferred_inline_size - - border_padding - margin, + border_padding - + margin, } } @@ -1599,9 +1879,13 @@ impl BlockFlow { } else { flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); for kid in self.base.children.iter() { - if kid.base().flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) { + if kid + .base() + .flags + .contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) + { flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS); - break + break; } } } @@ -1617,15 +1901,21 @@ impl BlockFlow { let (mut left_float_width_accumulator, mut right_float_width_accumulator) = (Au(0), Au(0)); let mut preferred_inline_size_of_children_without_text_or_replaced_fragments = Au(0); for kid in self.base.child_iter_mut() { - if kid.base().flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || !consult_children { - continue + if kid + .base() + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || + !consult_children + { + continue; } let child_base = kid.mut_base(); let float_kind = child_base.flags.float_kind(); - computation.content_intrinsic_sizes.minimum_inline_size = - max(computation.content_intrinsic_sizes.minimum_inline_size, - child_base.intrinsic_inline_sizes.minimum_inline_size); + computation.content_intrinsic_sizes.minimum_inline_size = max( + computation.content_intrinsic_sizes.minimum_inline_size, + child_base.intrinsic_inline_sizes.minimum_inline_size, + ); if child_base.flags.contains(FlowFlags::CLEARS_LEFT) { left_float_width = max(left_float_width, left_float_width_accumulator); @@ -1636,25 +1926,34 @@ impl BlockFlow { right_float_width_accumulator = Au(0) } - match (float_kind, child_base.flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS)) { + match ( + float_kind, + child_base + .flags + .contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS), + ) { (Float::None, true) => { - computation.content_intrinsic_sizes.preferred_inline_size = - max(computation.content_intrinsic_sizes.preferred_inline_size, - child_base.intrinsic_inline_sizes.preferred_inline_size); - } + computation.content_intrinsic_sizes.preferred_inline_size = max( + computation.content_intrinsic_sizes.preferred_inline_size, + child_base.intrinsic_inline_sizes.preferred_inline_size, + ); + }, (Float::None, false) => { preferred_inline_size_of_children_without_text_or_replaced_fragments = max( preferred_inline_size_of_children_without_text_or_replaced_fragments, - child_base.intrinsic_inline_sizes.preferred_inline_size) - } + child_base.intrinsic_inline_sizes.preferred_inline_size, + ) + }, (Float::Left, _) => { - left_float_width_accumulator = left_float_width_accumulator + - child_base.intrinsic_inline_sizes.preferred_inline_size; - } + left_float_width_accumulator = left_float_width_accumulator + child_base + .intrinsic_inline_sizes + .preferred_inline_size; + }, (Float::Right, _) => { - right_float_width_accumulator = right_float_width_accumulator + - child_base.intrinsic_inline_sizes.preferred_inline_size; - } + right_float_width_accumulator = right_float_width_accumulator + child_base + .intrinsic_inline_sizes + .preferred_inline_size; + }, } } @@ -1662,37 +1961,50 @@ impl BlockFlow { right_float_width = max(right_float_width, right_float_width_accumulator); computation.content_intrinsic_sizes.preferred_inline_size = - computation.content_intrinsic_sizes.preferred_inline_size + left_float_width + - right_float_width; - computation.content_intrinsic_sizes.preferred_inline_size = - max(computation.content_intrinsic_sizes.preferred_inline_size, - preferred_inline_size_of_children_without_text_or_replaced_fragments); + computation.content_intrinsic_sizes.preferred_inline_size + + left_float_width + + right_float_width; + computation.content_intrinsic_sizes.preferred_inline_size = max( + computation.content_intrinsic_sizes.preferred_inline_size, + preferred_inline_size_of_children_without_text_or_replaced_fragments, + ); self.base.intrinsic_inline_sizes = computation.finish(); self.base.flags = flags } pub fn overflow_style_may_require_clip_scroll_node(&self) -> bool { - match (self.fragment.style().get_box().overflow_x, - self.fragment.style().get_box().overflow_y) { - (StyleOverflow::Auto, _) | (StyleOverflow::Scroll, _) | (StyleOverflow::Hidden, _) | - (_, StyleOverflow::Auto) | (_, StyleOverflow::Scroll) | (_, StyleOverflow::Hidden) => - true, + match ( + self.fragment.style().get_box().overflow_x, + self.fragment.style().get_box().overflow_y, + ) { + (StyleOverflow::Auto, _) | + (StyleOverflow::Scroll, _) | + (StyleOverflow::Hidden, _) | + (_, StyleOverflow::Auto) | + (_, StyleOverflow::Scroll) | + (_, StyleOverflow::Hidden) => true, (_, _) => false, } } pub fn compute_inline_sizes(&mut self, shared_context: &SharedStyleContext) { - if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) { - return + if !self + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { + return; } - debug!("assign_inline_sizes({}): assigning inline_size for flow", - if self.base.flags.is_float() { - "float" - } else { - "block" - }); + debug!( + "assign_inline_sizes({}): assigning inline_size for flow", + if self.base.flags.is_float() { + "float" + } else { + "block" + } + ); self.base.floats = Floats::new(self.base.writing_mode); @@ -1712,8 +2024,9 @@ impl BlockFlow { if self.is_root() { debug!("Setting root position"); self.base.position.start = LogicalPoint::zero(self.base.writing_mode); - self.base.block_container_inline_size = LogicalSize::from_physical( - self.base.writing_mode, shared_context.viewport_size()).inline; + self.base.block_container_inline_size = + LogicalSize::from_physical(self.base.writing_mode, shared_context.viewport_size()) + .inline; self.base.block_container_writing_mode = self.base.writing_mode; } } @@ -1721,14 +2034,14 @@ impl BlockFlow { fn guess_inline_size_for_block_formatting_context_if_necessary(&mut self) { // We don't need to guess anything unless this is a block formatting context. if self.formatting_context_type() != FormattingContextType::Block { - return + return; } // If `max-width` is set, then don't perform this speculation. We guess that the // page set `max-width` in order to avoid hitting floats. The search box on Google // SERPs falls into this category. if self.fragment.style.max_inline_size() != LengthOrPercentageOrNone::None { - return + return; } // At this point, we know we can't precisely compute the inline-size of this block now, @@ -1736,39 +2049,51 @@ impl BlockFlow { // inline-size computed above minus the inline-size of the previous left and/or right // floats. let speculated_left_float_size = if self.fragment.margin.inline_start >= Au(0) && - self.base.speculated_float_placement_in.left > self.fragment.margin.inline_start { + self.base.speculated_float_placement_in.left > self.fragment.margin.inline_start + { self.base.speculated_float_placement_in.left - self.fragment.margin.inline_start } else { Au(0) }; let speculated_right_float_size = if self.fragment.margin.inline_end >= Au(0) && - self.base.speculated_float_placement_in.right > self.fragment.margin.inline_end { + self.base.speculated_float_placement_in.right > self.fragment.margin.inline_end + { self.base.speculated_float_placement_in.right - self.fragment.margin.inline_end } else { Au(0) }; self.fragment.border_box.size.inline = self.fragment.border_box.size.inline - - speculated_left_float_size - speculated_right_float_size + speculated_left_float_size - + speculated_right_float_size } fn definitely_has_zero_block_size(&self) -> bool { - if !self.fragment.style.content_block_size().is_definitely_zero() { - return false + if !self + .fragment + .style + .content_block_size() + .is_definitely_zero() + { + return false; } let border_width = self.fragment.border_width(); if border_width.block_start != Au(0) || border_width.block_end != Au(0) { - return false + return false; } let padding = self.fragment.style.logical_padding(); padding.block_start.is_definitely_zero() && padding.block_end.is_definitely_zero() } pub fn is_inline_flex_item(&self) -> bool { - self.fragment.flags.contains(FragmentFlags::IS_INLINE_FLEX_ITEM) + self.fragment + .flags + .contains(FragmentFlags::IS_INLINE_FLEX_ITEM) } pub fn is_block_flex_item(&self) -> bool { - self.fragment.flags.contains(FragmentFlags::IS_BLOCK_FLEX_ITEM) + self.fragment + .flags + .contains(FragmentFlags::IS_BLOCK_FLEX_ITEM) } pub fn mark_scrolling_overflow(&mut self, has_scrolling_overflow: bool) { @@ -1785,22 +2110,30 @@ impl BlockFlow { // Return offset from original position because of `position: sticky`. pub fn sticky_position(&self) -> SideOffsets2D<MaybeAuto> { - let containing_block_size = &self.base.early_absolute_position_info - .relative_containing_block_size; - let writing_mode = self.base.early_absolute_position_info.relative_containing_block_mode; + let containing_block_size = &self + .base + .early_absolute_position_info + .relative_containing_block_size; + let writing_mode = self + .base + .early_absolute_position_info + .relative_containing_block_mode; let offsets = self.fragment.style().logical_position(); - let as_margins = LogicalMargin::new(writing_mode, + let as_margins = LogicalMargin::new( + writing_mode, MaybeAuto::from_style(offsets.block_start, containing_block_size.inline), MaybeAuto::from_style(offsets.inline_end, containing_block_size.inline), MaybeAuto::from_style(offsets.block_end, containing_block_size.inline), - MaybeAuto::from_style(offsets.inline_start, containing_block_size.inline)); + MaybeAuto::from_style(offsets.inline_start, containing_block_size.inline), + ); as_margins.to_physical(writing_mode) } pub fn background_border_section(&self) -> DisplayListSection { if self.base.flags.is_float() { DisplayListSection::BackgroundAndBorders - } else if self.base + } else if self + .base .flags .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { @@ -1842,7 +2175,9 @@ impl Flow for BlockFlow { _ => true, }; self.bubble_inline_sizes_for_block(consult_children); - self.fragment.restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::BUBBLE_ISIZES); } /// Recursively (top-down) determines the actual inline-size of child contexts and fragments. @@ -1857,23 +2192,24 @@ impl Flow for BlockFlow { self.compute_inline_sizes(shared_context); // Move in from the inline-start border edge. - let inline_start_content_edge = self.fragment.border_box.start.i + - self.fragment.border_padding.inline_start; + let inline_start_content_edge = + self.fragment.border_box.start.i + self.fragment.border_padding.inline_start; let padding_and_borders = self.fragment.border_padding.inline_start_end(); // Distance from the inline-end margin edge to the inline-end content edge. let inline_end_content_edge = - self.fragment.margin.inline_end + - self.fragment.border_padding.inline_end; + self.fragment.margin.inline_end + self.fragment.border_padding.inline_end; let content_inline_size = self.fragment.border_box.size.inline - padding_and_borders; - self.propagate_assigned_inline_size_to_children(shared_context, - inline_start_content_edge, - inline_end_content_edge, - content_inline_size, - |_, _, _, _, _, _| {}); + self.propagate_assigned_inline_size_to_children( + shared_context, + inline_start_content_edge, + inline_end_content_edge, + content_inline_size, + |_, _, _, _, _, _| {}, + ); } fn place_float_if_applicable<'a>(&mut self) { @@ -1882,29 +2218,38 @@ impl Flow for BlockFlow { } } - fn assign_block_size_for_inorder_child_if_necessary(&mut self, - layout_context: &LayoutContext, - parent_thread_id: u8, - content_box: LogicalRect<Au>) - -> bool { + fn assign_block_size_for_inorder_child_if_necessary( + &mut self, + layout_context: &LayoutContext, + parent_thread_id: u8, + content_box: LogicalRect<Au>, + ) -> bool { if self.base.flags.is_float() { - return false + return false; } let is_formatting_context = self.formatting_context_type() != FormattingContextType::None; - if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && is_formatting_context { + if !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + is_formatting_context + { self.assign_inline_position_for_formatting_context(layout_context, content_box); } if (self as &Flow).floats_might_flow_through() { self.base.thread_id = parent_thread_id; - if self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | - ServoRestyleDamage::REFLOW) { + if self + .base + .restyle_damage + .intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) + { self.assign_block_size(layout_context); // Don't remove the restyle damage; `assign_block_size` decides whether that is // appropriate (which in the case of e.g. absolutely-positioned flows, it is not). } - return true + return true; } if is_formatting_context { @@ -1912,8 +2257,10 @@ impl Flow for BlockFlow { // translate the floats past us. let writing_mode = self.base.floats.writing_mode; let delta = self.base.position.size.block; - self.base.floats.translate(LogicalSize::new(writing_mode, Au(0), -delta)); - return true + self.base + .floats + .translate(LogicalSize::new(writing_mode, Au(0), -delta)); + return true; } false @@ -1924,47 +2271,68 @@ impl Flow for BlockFlow { debug_assert!(remaining.is_none()); } - fn fragment(&mut self, layout_context: &LayoutContext, - fragmentation_context: Option<FragmentationContext>) - -> Option<Arc<Flow>> { + fn fragment( + &mut self, + layout_context: &LayoutContext, + fragmentation_context: Option<FragmentationContext>, + ) -> Option<Arc<Flow>> { if self.fragment.is_replaced() { - let _scope = layout_debug_scope!("assign_replaced_block_size_if_necessary {:x}", - self.base.debug_id()); + let _scope = layout_debug_scope!( + "assign_replaced_block_size_if_necessary {:x}", + self.base.debug_id() + ); // Assign block-size for fragment if it is an image fragment. self.fragment.assign_replaced_block_size_if_necessary(); - if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { + if !self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { self.base.position.size.block = self.fragment.border_box.size.block; - let mut block_start = AdjoiningMargins::from_margin(self.fragment.margin.block_start); + let mut block_start = + AdjoiningMargins::from_margin(self.fragment.margin.block_start); let block_end = AdjoiningMargins::from_margin(self.fragment.margin.block_end); if self.fragment.border_box.size.block == Au(0) { block_start.union(block_end); - self.base.collapsible_margins = CollapsibleMargins::CollapseThrough(block_start); + self.base.collapsible_margins = + CollapsibleMargins::CollapseThrough(block_start); } else { - self.base.collapsible_margins = CollapsibleMargins::Collapse(block_start, block_end); + self.base.collapsible_margins = + CollapsibleMargins::Collapse(block_start, block_end); } - self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); - self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | - ServoRestyleDamage::REFLOW); + self.base + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); + self.fragment + .restyle_damage + .remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW); } None } else if self.is_root() || - self.formatting_context_type() != FormattingContextType::None || - self.base.flags.contains(FlowFlags::MARGINS_CANNOT_COLLAPSE) { + self.formatting_context_type() != FormattingContextType::None || + self.base.flags.contains(FlowFlags::MARGINS_CANNOT_COLLAPSE) + { // Root element margins should never be collapsed according to CSS § 8.3.1. - debug!("assign_block_size: assigning block_size for root flow {:?}", - self.base().debug_id()); + debug!( + "assign_block_size: assigning block_size for root flow {:?}", + self.base().debug_id() + ); self.assign_block_size_block_base( layout_context, fragmentation_context, - MarginsMayCollapseFlag::MarginsMayNotCollapse) + MarginsMayCollapseFlag::MarginsMayNotCollapse, + ) } else { - debug!("assign_block_size: assigning block_size for block {:?}", - self.base().debug_id()); + debug!( + "assign_block_size: assigning block_size for block {:?}", + self.base().debug_id() + ); self.assign_block_size_block_base( layout_context, fragmentation_context, - MarginsMayCollapseFlag::MarginsMayCollapse) + MarginsMayCollapseFlag::MarginsMayCollapse, + ) } } @@ -1977,9 +2345,16 @@ impl Flow for BlockFlow { self.base.clip = Rect::max_rect(); } - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { - let position_start = self.base.position.start.to_physical(self.base.writing_mode, - container_size); + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) + { + let position_start = self + .base + .position + .start + .to_physical(self.base.writing_mode, container_size); // Compute our position relative to the nearest ancestor stacking context. This will be // passed down later as part of containing block details for absolute descendants. @@ -1991,21 +2366,38 @@ impl Flow for BlockFlow { // flow w.r.t. the containing block. self.base .late_absolute_position_info - .stacking_relative_position_of_absolute_containing_block + position_start.to_vector() + .stacking_relative_position_of_absolute_containing_block + + position_start.to_vector() }; if !self.base.writing_mode.is_vertical() { - if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { self.base.stacking_relative_position.x = absolute_stacking_relative_position.x } - if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { self.base.stacking_relative_position.y = absolute_stacking_relative_position.y } } else { - if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { self.base.stacking_relative_position.y = absolute_stacking_relative_position.y } - if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if !self + .base + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { self.base.stacking_relative_position.x = absolute_stacking_relative_position.x } } @@ -2014,28 +2406,33 @@ impl Flow for BlockFlow { // For relatively-positioned descendants, the containing block formed by a block is just // the content box. The containing block for absolutely-positioned descendants, on the // other hand, is established in other circumstances (see `is_absolute_containing_block'). - let relative_offset = - self.fragment.relative_position(&self.base - .early_absolute_position_info - .relative_containing_block_size); + let relative_offset = self.fragment.relative_position( + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + ); if self.is_absolute_containing_block() { - let border_box_origin = (self.fragment.border_box - - self.fragment.style.logical_border_width()).start; + let border_box_origin = + (self.fragment.border_box - self.fragment.style.logical_border_width()).start; self.base .late_absolute_position_info .stacking_relative_position_of_absolute_containing_block = - self.base.stacking_relative_position.to_point() + - (border_box_origin + relative_offset).to_physical(self.base.writing_mode, - container_size).to_vector() + self.base.stacking_relative_position.to_point() + + (border_box_origin + relative_offset) + .to_physical(self.base.writing_mode, container_size) + .to_vector() } // Compute absolute position info for children. let stacking_relative_position_of_absolute_containing_block_for_children = if self.fragment.establishes_stacking_context() { let logical_border_width = self.fragment.style().logical_border_width(); - let position = LogicalPoint::new(self.base.writing_mode, - logical_border_width.inline_start, - logical_border_width.block_start); + let position = LogicalPoint::new( + self.base.writing_mode, + logical_border_width.inline_start, + logical_border_width.block_start, + ); let position = position.to_physical(self.base.writing_mode, container_size); // Some blocks establish a stacking context, but not a containing block for @@ -2061,7 +2458,9 @@ impl Flow for BlockFlow { self.base.position.size.to_physical(self.base.writing_mode); // Compute the origin and clipping rectangle for children. - let relative_offset = relative_offset.to_physical(self.base.writing_mode).to_vector(); + let relative_offset = relative_offset + .to_physical(self.base.writing_mode) + .to_vector(); let is_stacking_context = self.fragment.establishes_stacking_context(); let origin_for_children = if is_stacking_context { // We establish a stacking context, so the position of our children is vertically @@ -2078,36 +2477,48 @@ impl Flow for BlockFlow { // Process children. for kid in self.base.child_iter_mut() { - if kid.base().flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) || - kid.base().flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { + if kid + .base() + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) || + kid.base() + .flags + .contains(FlowFlags::BLOCK_POSITION_IS_STATIC) + { let kid_base = kid.mut_base(); - let physical_position = kid_base.position.to_physical(kid_base.writing_mode, - container_size_for_children); + let physical_position = kid_base + .position + .to_physical(kid_base.writing_mode, container_size_for_children); // Set the inline and block positions as necessary. if !kid_base.writing_mode.is_vertical() { - if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.x = origin_for_children.x + - physical_position.origin.x + if kid_base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { + kid_base.stacking_relative_position.x = + origin_for_children.x + physical_position.origin.x } if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.y = origin_for_children.y + - physical_position.origin.y + kid_base.stacking_relative_position.y = + origin_for_children.y + physical_position.origin.y } } else { - if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.y = origin_for_children.y + - physical_position.origin.y + if kid_base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { + kid_base.stacking_relative_position.y = + origin_for_children.y + physical_position.origin.y } if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) { - kid_base.stacking_relative_position.x = origin_for_children.x + - physical_position.origin.x + kid_base.stacking_relative_position.x = + origin_for_children.x + physical_position.origin.x } } } - kid.mut_base().late_absolute_position_info = - late_absolute_position_info_for_children; + kid.mut_base().late_absolute_position_info = late_absolute_position_info_for_children; } } @@ -2132,8 +2543,9 @@ impl Flow for BlockFlow { /// Returns true if this flow contains fragments that are roots of an absolute flow tree. fn contains_roots_of_absolute_flow_tree(&self) -> bool { - self.contains_relatively_positioned_fragments() || self.is_root() || - self.fragment.has_filter_transform_or_perspective() + self.contains_relatively_positioned_fragments() || + self.is_root() || + self.fragment.has_filter_transform_or_perspective() } /// Returns true if this is an absolute containing block. @@ -2142,21 +2554,27 @@ impl Flow for BlockFlow { } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && - self.fragment.style().logical_position().inline_start == - LengthOrPercentageOrAuto::Auto && - self.fragment.style().logical_position().inline_end == - LengthOrPercentageOrAuto::Auto { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + self.fragment.style().logical_position().inline_start == + LengthOrPercentageOrAuto::Auto && + self.fragment.style().logical_position().inline_end == LengthOrPercentageOrAuto::Auto + { self.base.position.start.i = inline_position } } fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) { - if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && - self.fragment.style().logical_position().block_start == - LengthOrPercentageOrAuto::Auto && - self.fragment.style().logical_position().block_end == - LengthOrPercentageOrAuto::Auto { + if self + .base + .flags + .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && + self.fragment.style().logical_position().block_start == + LengthOrPercentageOrAuto::Auto && + self.fragment.style().logical_position().block_end == LengthOrPercentageOrAuto::Auto + { self.base.position.start.b = block_position } } @@ -2175,33 +2593,43 @@ impl Flow for BlockFlow { fn compute_overflow(&self) -> Overflow { let flow_size = self.base.position.size.to_physical(self.base.writing_mode); - let overflow = self.fragment.compute_overflow(&flow_size, - &self.base - .early_absolute_position_info - .relative_containing_block_size); + let overflow = self.fragment.compute_overflow( + &flow_size, + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + ); overflow } - fn iterate_through_fragment_border_boxes(&self, - iterator: &mut FragmentBorderBoxIterator, - level: i32, - stacking_context_position: &Point2D<Au>) { + fn iterate_through_fragment_border_boxes( + &self, + iterator: &mut FragmentBorderBoxIterator, + level: i32, + stacking_context_position: &Point2D<Au>, + ) { if !iterator.should_process(&self.fragment) { - return + return; } - iterator.process(&self.fragment, - level, - &self.fragment - .stacking_relative_border_box(&self.base.stacking_relative_position, - &self.base - .early_absolute_position_info - .relative_containing_block_size, - self.base - .early_absolute_position_info - .relative_containing_block_mode, - CoordinateSystem::Own) - .translate(&stacking_context_position.to_vector())); + iterator.process( + &self.fragment, + level, + &self + .fragment + .stacking_relative_border_box( + &self.base.stacking_relative_position, + &self + .base + .early_absolute_position_info + .relative_containing_block_size, + self.base + .early_absolute_position_info + .relative_containing_block_mode, + CoordinateSystem::Own, + ).translate(&stacking_context_position.to_vector()), + ); } fn mutate_fragments(&mut self, mutator: &mut FnMut(&mut Fragment)) { @@ -2215,11 +2643,13 @@ impl Flow for BlockFlow { impl fmt::Debug for BlockFlow { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, - "{:?}({:x}) {:?}", - self.class(), - self.base.debug_id(), - self.base) + write!( + f, + "{:?}({:x}) {:?}", + self.class(), + self.base.debug_id(), + self.base + ) } } @@ -2236,14 +2666,15 @@ pub struct ISizeConstraintInput { } impl ISizeConstraintInput { - pub fn new(computed_inline_size: MaybeAuto, - inline_start_margin: MaybeAuto, - inline_end_margin: MaybeAuto, - inline_start: MaybeAuto, - inline_end: MaybeAuto, - text_align: TextAlign, - available_inline_size: Au) - -> ISizeConstraintInput { + pub fn new( + computed_inline_size: MaybeAuto, + inline_start_margin: MaybeAuto, + inline_end_margin: MaybeAuto, + inline_start: MaybeAuto, + inline_end: MaybeAuto, + text_align: TextAlign, + available_inline_size: Au, + ) -> ISizeConstraintInput { ISizeConstraintInput { computed_inline_size: computed_inline_size, inline_start_margin: inline_start_margin, @@ -2262,12 +2693,15 @@ pub struct ISizeConstraintSolution { pub inline_start: Au, pub inline_size: Au, pub margin_inline_start: Au, - pub margin_inline_end: Au + pub margin_inline_end: Au, } impl ISizeConstraintSolution { - pub fn new(inline_size: Au, margin_inline_start: Au, margin_inline_end: Au) - -> ISizeConstraintSolution { + pub fn new( + inline_size: Au, + margin_inline_start: Au, + margin_inline_end: Au, + ) -> ISizeConstraintSolution { ISizeConstraintSolution { inline_start: Au(0), inline_size: inline_size, @@ -2276,11 +2710,12 @@ impl ISizeConstraintSolution { } } - fn for_absolute_flow(inline_start: Au, - inline_size: Au, - margin_inline_start: Au, - margin_inline_end: Au) - -> ISizeConstraintSolution { + fn for_absolute_flow( + inline_start: Au, + inline_size: Au, + margin_inline_start: Au, + margin_inline_end: Au, + ) -> ISizeConstraintSolution { ISizeConstraintSolution { inline_start: inline_start, inline_size: inline_size, @@ -2296,54 +2731,57 @@ impl ISizeConstraintSolution { pub trait ISizeAndMarginsComputer { /// Instructs the fragment to compute its border and padding. fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) { - block.fragment.compute_border_and_padding(containing_block_inline_size); + block + .fragment + .compute_border_and_padding(containing_block_inline_size); } /// Compute the inputs for the ISize constraint equation. /// /// This is called only once to compute the initial inputs. For calculations involving /// minimum and maximum inline-size, we don't need to recompute these. - fn compute_inline_size_constraint_inputs(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> ISizeConstraintInput { + fn compute_inline_size_constraint_inputs( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> ISizeConstraintInput { let containing_block_inline_size = self.containing_block_inline_size(block, parent_flow_inline_size, shared_context); - block.fragment.compute_block_direction_margins(containing_block_inline_size); - block.fragment.compute_inline_direction_margins(containing_block_inline_size); + block + .fragment + .compute_block_direction_margins(containing_block_inline_size); + block + .fragment + .compute_inline_direction_margins(containing_block_inline_size); self.compute_border_and_padding(block, containing_block_inline_size); - let mut computed_inline_size = self.initial_computed_inline_size(block, - parent_flow_inline_size, - shared_context); + let mut computed_inline_size = + self.initial_computed_inline_size(block, parent_flow_inline_size, shared_context); let style = block.fragment.style(); match (computed_inline_size, style.get_position().box_sizing) { (MaybeAuto::Specified(size), BoxSizing::BorderBox) => { computed_inline_size = MaybeAuto::Specified(size - block.fragment.border_padding.inline_start_end()) - } - (MaybeAuto::Auto, BoxSizing::BorderBox) | - (_, BoxSizing::ContentBox) => {} + }, + (MaybeAuto::Auto, BoxSizing::BorderBox) | (_, BoxSizing::ContentBox) => {}, } let margin = style.logical_margin(); let position = style.logical_position(); - let available_inline_size = containing_block_inline_size - - block.fragment.border_padding.inline_start_end(); - ISizeConstraintInput::new(computed_inline_size, - MaybeAuto::from_style(margin.inline_start, - containing_block_inline_size), - MaybeAuto::from_style(margin.inline_end, - containing_block_inline_size), - MaybeAuto::from_style(position.inline_start, - containing_block_inline_size), - MaybeAuto::from_style(position.inline_end, - containing_block_inline_size), - style.get_inherited_text().text_align, - available_inline_size) + let available_inline_size = + containing_block_inline_size - block.fragment.border_padding.inline_start_end(); + ISizeConstraintInput::new( + computed_inline_size, + MaybeAuto::from_style(margin.inline_start, containing_block_inline_size), + MaybeAuto::from_style(margin.inline_end, containing_block_inline_size), + MaybeAuto::from_style(position.inline_start, containing_block_inline_size), + MaybeAuto::from_style(position.inline_end, containing_block_inline_size), + style.get_inherited_text().text_align, + available_inline_size, + ) } /// Set the used values for inline-size and margins from the relevant constraint equation. @@ -2355,9 +2793,11 @@ pub trait ISizeAndMarginsComputer { /// * Inline-start coordinate of this flow's box; /// * Inline-start coordinate of the flow with respect to its containing block (if this is an /// absolute flow). - fn set_inline_size_constraint_solutions(&self, - block: &mut BlockFlow, - solution: ISizeConstraintSolution) { + fn set_inline_size_constraint_solutions( + &self, + block: &mut BlockFlow, + solution: ISizeConstraintSolution, + ) { let inline_size; let extra_inline_size_from_margin; { @@ -2388,8 +2828,8 @@ pub trait ISizeAndMarginsComputer { // To calculate the total size of this block, we also need to account for any // additional size contribution from positive margins. Negative margins means the block // isn't made larger at all by the margin. - extra_inline_size_from_margin = max(Au(0), fragment.margin.inline_start) + - max(Au(0), fragment.margin.inline_end); + extra_inline_size_from_margin = + max(Au(0), fragment.margin.inline_start) + max(Au(0), fragment.margin.inline_end); } // We also resize the block itself, to ensure that overflow is not calculated @@ -2399,45 +2839,55 @@ pub trait ISizeAndMarginsComputer { } /// Set the inline coordinate of the given flow if it is absolutely positioned. - fn set_inline_position_of_flow_if_necessary(&self, - _: &mut BlockFlow, - _: ISizeConstraintSolution) {} + fn set_inline_position_of_flow_if_necessary( + &self, + _: &mut BlockFlow, + _: ISizeConstraintSolution, + ) { + } /// Solve the inline-size and margins constraints for this block flow. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution; - - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { - MaybeAuto::from_style(block.fragment().style().content_inline_size(), - self.containing_block_inline_size(block, - parent_flow_inline_size, - shared_context)) - } - - fn containing_block_inline_size(&self, - _: &mut BlockFlow, - parent_flow_inline_size: Au, - _: &SharedStyleContext) - -> Au { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution; + + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { + MaybeAuto::from_style( + block.fragment().style().content_inline_size(), + self.containing_block_inline_size(block, parent_flow_inline_size, shared_context), + ) + } + + fn containing_block_inline_size( + &self, + _: &mut BlockFlow, + parent_flow_inline_size: Au, + _: &SharedStyleContext, + ) -> Au { parent_flow_inline_size } /// Compute the used value of inline-size, taking care of min-inline-size and max-inline-size. /// /// CSS Section 10.4: Minimum and Maximum inline-sizes - fn compute_used_inline_size(&self, - block: &mut BlockFlow, - shared_context: &SharedStyleContext, - parent_flow_inline_size: Au) { - let mut input = self.compute_inline_size_constraint_inputs(block, - parent_flow_inline_size, - shared_context); + fn compute_used_inline_size( + &self, + block: &mut BlockFlow, + shared_context: &SharedStyleContext, + parent_flow_inline_size: Au, + ) { + let mut input = self.compute_inline_size_constraint_inputs( + block, + parent_flow_inline_size, + shared_context, + ); let containing_block_inline_size = self.containing_block_inline_size(block, parent_flow_inline_size, shared_context); @@ -2447,19 +2897,27 @@ pub trait ISizeAndMarginsComputer { // If the tentative used inline-size is greater than 'max-inline-size', inline-size should // be recalculated, but this time using the computed value of 'max-inline-size' as the // computed value for 'inline-size'. - match block.fragment().style().max_inline_size().to_used_value(containing_block_inline_size) { + match block + .fragment() + .style() + .max_inline_size() + .to_used_value(containing_block_inline_size) + { Some(max_inline_size) if max_inline_size < solution.inline_size => { input.computed_inline_size = MaybeAuto::Specified(max_inline_size); solution = self.solve_inline_size_constraints(block, &input); - } - _ => {} + }, + _ => {}, } // If the resulting inline-size is smaller than 'min-inline-size', inline-size should be // recalculated, but this time using the value of 'min-inline-size' as the computed value // for 'inline-size'. - let computed_min_inline_size = - block.fragment().style().min_inline_size().to_used_value(containing_block_inline_size); + let computed_min_inline_size = block + .fragment() + .style() + .min_inline_size() + .to_used_value(containing_block_inline_size); if computed_min_inline_size > solution.inline_size { input.computed_inline_size = MaybeAuto::Specified(computed_min_inline_size); solution = self.solve_inline_size_constraints(block, &input); @@ -2477,15 +2935,17 @@ pub trait ISizeAndMarginsComputer { /// Constraint Equation: margin-inline-start + margin-inline-end + inline-size = /// available_inline-size /// where available_inline-size = CB inline-size - (horizontal border + padding) - fn solve_block_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + fn solve_block_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); // Check for direction of parent flow (NOT Containing Block) let block_mode = block.base.writing_mode; @@ -2504,11 +2964,14 @@ pub trait ISizeAndMarginsComputer { let inline_end = inline_end_margin.specified_or_zero(); if (inline_start + inline_end + inline_size) > available_inline_size { - (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end)) + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Specified(inline_end), + ) } else { (inline_start_margin, inline_end_margin) } - } + }, }; // Invariant: inline-start_margin + inline-size + inline-end_margin == @@ -2516,9 +2979,11 @@ pub trait ISizeAndMarginsComputer { let (inline_start_margin, inline_size, inline_end_margin) = match (inline_start_margin, computed_inline_size, inline_end_margin) { // If all have a computed value other than 'auto', the system is over-constrained. - (MaybeAuto::Specified(margin_start), - MaybeAuto::Specified(inline_size), - MaybeAuto::Specified(margin_end)) => { + ( + MaybeAuto::Specified(margin_start), + MaybeAuto::Specified(inline_size), + MaybeAuto::Specified(margin_end), + ) => { // servo_left, servo_right, and servo_center are used to implement // the "align descendants" rule in HTML5 § 14.2. if block_align == TextAlign::ServoCenter { @@ -2533,52 +2998,66 @@ pub trait ISizeAndMarginsComputer { _ => parent_has_same_direction, }; if ignore_end_margin { - (margin_start, inline_size, available_inline_size - - (margin_start + inline_size)) + ( + margin_start, + inline_size, + available_inline_size - (margin_start + inline_size), + ) } else { - (available_inline_size - (margin_end + inline_size), - inline_size, - margin_end) + ( + available_inline_size - (margin_end + inline_size), + inline_size, + margin_end, + ) } } - } + }, // If exactly one value is 'auto', solve for it - (MaybeAuto::Auto, - MaybeAuto::Specified(inline_size), - MaybeAuto::Specified(margin_end)) => - (available_inline_size - (inline_size + margin_end), inline_size, margin_end), - (MaybeAuto::Specified(margin_start), - MaybeAuto::Auto, - MaybeAuto::Specified(margin_end)) => { - (margin_start, - available_inline_size - (margin_start + margin_end), - margin_end) - } - (MaybeAuto::Specified(margin_start), - MaybeAuto::Specified(inline_size), - MaybeAuto::Auto) => { - (margin_start, - inline_size, - available_inline_size - (margin_start + inline_size)) - } + ( + MaybeAuto::Auto, + MaybeAuto::Specified(inline_size), + MaybeAuto::Specified(margin_end), + ) => ( + available_inline_size - (inline_size + margin_end), + inline_size, + margin_end, + ), + ( + MaybeAuto::Specified(margin_start), + MaybeAuto::Auto, + MaybeAuto::Specified(margin_end), + ) => ( + margin_start, + available_inline_size - (margin_start + margin_end), + margin_end, + ), + ( + MaybeAuto::Specified(margin_start), + MaybeAuto::Specified(inline_size), + MaybeAuto::Auto, + ) => ( + margin_start, + inline_size, + available_inline_size - (margin_start + inline_size), + ), // If inline-size is set to 'auto', any other 'auto' value becomes '0', // and inline-size is solved for (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => { (Au(0), available_inline_size - margin_end, margin_end) - } + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Auto, MaybeAuto::Auto) => { (margin_start, available_inline_size - margin_start, Au(0)) - } + }, (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => { (Au(0), available_inline_size, Au(0)) - } + }, // If inline-start and inline-end margins are auto, they become equal (MaybeAuto::Auto, MaybeAuto::Specified(inline_size), MaybeAuto::Auto) => { let margin = (available_inline_size - inline_size).scale_by(0.5); (margin, inline_size, margin) - } + }, }; ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin) @@ -2609,10 +3088,11 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { /// [aka available inline-size] /// /// Return the solution for the equation. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { let &ISizeConstraintInput { computed_inline_size, inline_start_margin, @@ -2639,14 +3119,16 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { // and inline-size Auto. // Set inline-end to zero to calculate inline-size. - let inline_size = - block.get_shrink_to_fit_inline_size(available_inline_size - - (margin_start + margin_end)); + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); (Au(0), inline_size, margin_start, margin_end) - } - (MaybeAuto::Specified(inline_start), - MaybeAuto::Specified(inline_end), - MaybeAuto::Specified(inline_size)) => { + }, + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Specified(inline_end), + MaybeAuto::Specified(inline_size), + ) => { match (inline_start_margin, inline_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { let total_margin_val = @@ -2662,20 +3144,32 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { } } else { // Equal margins - (inline_start, - inline_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) + ( + inline_start, + inline_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) } - } + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => { let sum = inline_start + inline_end + inline_size + margin_start; - (inline_start, inline_size, margin_start, available_inline_size - sum) - } + ( + inline_start, + inline_size, + margin_start, + available_inline_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => { let sum = inline_start + inline_end + inline_size + margin_end; - (inline_start, inline_size, available_inline_size - sum, margin_end) - } + ( + inline_start, + inline_size, + available_inline_size - sum, + margin_end, + ) + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => { // Values are over-constrained. let sum = inline_start + inline_size + margin_start + margin_end; @@ -2684,40 +3178,58 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { (inline_start, inline_size, margin_start, margin_end) } else { // Ignore value for 'inline-start' - (available_inline_size - sum, - inline_size, - margin_start, - margin_end) + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) } - } + }, } - } + }, // For the rest of the cases, auto values for margin are set to 0 // If only one is Auto, solve for it - (MaybeAuto::Auto, - MaybeAuto::Specified(inline_end), - MaybeAuto::Specified(inline_size)) => { + ( + MaybeAuto::Auto, + MaybeAuto::Specified(inline_end), + MaybeAuto::Specified(inline_size), + ) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); let sum = inline_end + inline_size + margin_start + margin_end; - (available_inline_size - sum, inline_size, margin_start, margin_end) - } - (MaybeAuto::Specified(inline_start), - MaybeAuto::Auto, - MaybeAuto::Specified(inline_size)) => { + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) + }, + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Auto, + MaybeAuto::Specified(inline_size), + ) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); (inline_start, inline_size, margin_start, margin_end) - } - (MaybeAuto::Specified(inline_start), - MaybeAuto::Specified(inline_end), - MaybeAuto::Auto) => { + }, + ( + MaybeAuto::Specified(inline_start), + MaybeAuto::Specified(inline_end), + MaybeAuto::Auto, + ) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); let sum = inline_start + inline_end + margin_start + margin_end; - (inline_start, available_inline_size - sum, margin_start, margin_end) - } + ( + inline_start, + available_inline_size - sum, + margin_start, + margin_end, + ) + }, // If inline-size is auto, then inline-size is shrink-to-fit. Solve for the // non-auto value. @@ -2725,21 +3237,26 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); // Set inline-end to zero to calculate inline-size - let inline_size = - block.get_shrink_to_fit_inline_size(available_inline_size - - (margin_start + margin_end)); + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); (inline_start, inline_size, margin_start, margin_end) - } + }, (MaybeAuto::Auto, MaybeAuto::Specified(inline_end), MaybeAuto::Auto) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); // Set inline-start to zero to calculate inline-size - let inline_size = - block.get_shrink_to_fit_inline_size(available_inline_size - - (margin_start + margin_end)); + let inline_size = block.get_shrink_to_fit_inline_size( + available_inline_size - (margin_start + margin_end), + ); let sum = inline_end + inline_size + margin_start + margin_end; - (available_inline_size - sum, inline_size, margin_start, margin_end) - } + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) + }, (MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(inline_size)) => { let margin_start = inline_start_margin.specified_or_zero(); @@ -2747,28 +3264,39 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { // Setting 'inline-start' to static position because direction is 'ltr'. // TODO: Handle 'rtl' when it is implemented. (Au(0), inline_size, margin_start, margin_end) - } + }, }; - ISizeConstraintSolution::for_absolute_flow(inline_start, - inline_size, - margin_inline_start, - margin_inline_end) - } - - fn containing_block_inline_size(&self, - block: &mut BlockFlow, - _: Au, - shared_context: &SharedStyleContext) - -> Au { + ISizeConstraintSolution::for_absolute_flow( + inline_start, + inline_size, + margin_inline_start, + margin_inline_end, + ) + } + + fn containing_block_inline_size( + &self, + block: &mut BlockFlow, + _: Au, + shared_context: &SharedStyleContext, + ) -> Au { let opaque_block = OpaqueFlow::from_flow(block); - block.containing_block_size(&shared_context.viewport_size(), opaque_block).inline + block + .containing_block_size(&shared_context.viewport_size(), opaque_block) + .inline } - fn set_inline_position_of_flow_if_necessary(&self, - block: &mut BlockFlow, - solution: ISizeConstraintSolution) { + fn set_inline_position_of_flow_if_necessary( + &self, + block: &mut BlockFlow, + solution: ISizeConstraintSolution, + ) { // Set the inline position of the absolute flow wrt to its containing block. - if !block.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) { + if !block + .base + .flags + .contains(FlowFlags::INLINE_POSITION_IS_STATIC) + { block.base.position.start.i = solution.inline_start; } } @@ -2784,8 +3312,11 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { /// [aka available_inline-size] /// /// Return the solution for the equation. - fn solve_inline_size_constraints(&self, _: &mut BlockFlow, input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + _: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { let &ISizeConstraintInput { computed_inline_size, inline_start_margin, @@ -2803,9 +3334,11 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { let inline_size = match computed_inline_size { MaybeAuto::Specified(w) => w, - _ => panic!("{} {}", - "The used value for inline_size for absolute replaced flow", - "should have already been calculated by now.") + _ => panic!( + "{} {}", + "The used value for inline_size for absolute replaced flow", + "should have already been calculated by now." + ), }; let (inline_start, inline_size, margin_inline_start, margin_inline_end) = @@ -2814,86 +3347,115 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); (Au(0), inline_size, margin_start, margin_end) - } + }, // If only one is Auto, solve for it (MaybeAuto::Auto, MaybeAuto::Specified(inline_end)) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); let sum = inline_end + inline_size + margin_start + margin_end; - (available_inline_size - sum, inline_size, margin_start, margin_end) - } + ( + available_inline_size - sum, + inline_size, + margin_start, + margin_end, + ) + }, (MaybeAuto::Specified(inline_start), MaybeAuto::Auto) => { let margin_start = inline_start_margin.specified_or_zero(); let margin_end = inline_end_margin.specified_or_zero(); (inline_start, inline_size, margin_start, margin_end) - } + }, (MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end)) => { match (inline_start_margin, inline_end_margin) { (MaybeAuto::Auto, MaybeAuto::Auto) => { - let total_margin_val = available_inline_size - inline_start - - inline_end - inline_size; + let total_margin_val = + available_inline_size - inline_start - inline_end - inline_size; if total_margin_val < Au(0) { // margin-inline-start becomes 0 because direction is 'ltr'. (inline_start, inline_size, Au(0), total_margin_val) } else { // Equal margins - (inline_start, - inline_size, - total_margin_val.scale_by(0.5), - total_margin_val.scale_by(0.5)) + ( + inline_start, + inline_size, + total_margin_val.scale_by(0.5), + total_margin_val.scale_by(0.5), + ) } - } + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => { let sum = inline_start + inline_end + inline_size + margin_start; - (inline_start, inline_size, margin_start, available_inline_size - sum) - } + ( + inline_start, + inline_size, + margin_start, + available_inline_size - sum, + ) + }, (MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => { let sum = inline_start + inline_end + inline_size + margin_end; - (inline_start, inline_size, available_inline_size - sum, margin_end) - } + ( + inline_start, + inline_size, + available_inline_size - sum, + margin_end, + ) + }, (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => { // Values are over-constrained. // Ignore value for 'inline-end' cos direction is 'ltr'. (inline_start, inline_size, margin_start, margin_end) - } + }, } - } + }, }; - ISizeConstraintSolution::for_absolute_flow(inline_start, - inline_size, - margin_inline_start, - margin_inline_end) + ISizeConstraintSolution::for_absolute_flow( + inline_start, + inline_size, + margin_inline_start, + margin_inline_end, + ) } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - _: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + _: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let opaque_block = OpaqueFlow::from_flow(block); - let containing_block_inline_size = - block.containing_block_size(&shared_context.viewport_size(), opaque_block).inline; + let containing_block_inline_size = block + .containing_block_size(&shared_context.viewport_size(), opaque_block) + .inline; let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(containing_block_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + containing_block_inline_size, + container_block_size, + ); // For replaced absolute flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) } - fn containing_block_inline_size(&self, - block: &mut BlockFlow, - _: Au, - shared_context: &SharedStyleContext) - -> Au { + fn containing_block_inline_size( + &self, + block: &mut BlockFlow, + _: Au, + shared_context: &SharedStyleContext, + ) -> Au { let opaque_block = OpaqueFlow::from_flow(block); - block.containing_block_size(&shared_context.viewport_size(), opaque_block).inline + block + .containing_block_size(&shared_context.viewport_size(), opaque_block) + .inline } - fn set_inline_position_of_flow_if_necessary(&self, - block: &mut BlockFlow, - solution: ISizeConstraintSolution) { + fn set_inline_position_of_flow_if_necessary( + &self, + block: &mut BlockFlow, + solution: ISizeConstraintSolution, + ) { // Set the x-coordinate of the absolute flow wrt to its containing block. block.base.position.start.i = solution.inline_start; } @@ -2901,10 +3463,11 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { impl ISizeAndMarginsComputer for BlockNonReplaced { /// Compute inline-start and inline-end margins and inline-size. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { self.solve_block_inline_size_constraints(block, input) } } @@ -2914,55 +3477,64 @@ impl ISizeAndMarginsComputer for BlockReplaced { /// /// ISize has already been calculated. We now calculate the margins just /// like for non-replaced blocks. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { match input.computed_inline_size { MaybeAuto::Specified(_) => {}, MaybeAuto::Auto => { panic!("BlockReplaced: inline_size should have been computed by now") - } + }, }; self.solve_block_inline_size_constraints(block, input) } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) } - } impl ISizeAndMarginsComputer for FloatNonReplaced { /// CSS Section 10.3.5 /// /// If inline-size is computed as 'auto', the used value is the 'shrink-to-fit' inline-size. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); let margin_inline_start = inline_start_margin.specified_or_zero(); let margin_inline_end = inline_end_margin.specified_or_zero(); - let available_inline_size_float = available_inline_size - margin_inline_start - - margin_inline_end; + let available_inline_size_float = + available_inline_size - margin_inline_start - margin_inline_end; let shrink_to_fit = block.get_shrink_to_fit_inline_size(available_inline_size_float); let inline_size = computed_inline_size.specified_or_default(shrink_to_fit); - debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); + debug!( + "assign_inline_sizes_float -- inline_size: {:?}", + inline_size + ); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } } @@ -2971,29 +3543,44 @@ impl ISizeAndMarginsComputer for FloatReplaced { /// CSS Section 10.3.5 /// /// If inline-size is computed as 'auto', the used value is the 'shrink-to-fit' inline-size. - fn solve_inline_size_constraints(&self, _: &mut BlockFlow, input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, inline_start_margin, inline_end_margin) = - (input.computed_inline_size, input.inline_start_margin, input.inline_end_margin); + fn solve_inline_size_constraints( + &self, + _: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + ); let margin_inline_start = inline_start_margin.specified_or_zero(); let margin_inline_end = inline_end_margin.specified_or_zero(); let inline_size = match computed_inline_size { MaybeAuto::Specified(w) => w, - MaybeAuto::Auto => panic!("FloatReplaced: inline_size should have been computed by now") + MaybeAuto::Auto => { + panic!("FloatReplaced: inline_size should have been computed by now") + }, }; - debug!("assign_inline_sizes_float -- inline_size: {:?}", inline_size); + debug!( + "assign_inline_sizes_float -- inline_size: {:?}", + inline_size + ); ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end) } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) @@ -3002,18 +3589,17 @@ impl ISizeAndMarginsComputer for FloatReplaced { impl ISizeAndMarginsComputer for InlineBlockNonReplaced { /// Compute inline-start and inline-end margins and inline-size. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { - let (computed_inline_size, - inline_start_margin, - inline_end_margin, - available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); // For inline-blocks, `auto` margins compute to 0. let inline_start_margin = inline_start_margin.specified_or_zero(); @@ -3022,10 +3608,9 @@ impl ISizeAndMarginsComputer for InlineBlockNonReplaced { // If inline-size is set to 'auto', and this is an inline block, use the // shrink to fit algorithm (see CSS 2.1 § 10.3.9) let inline_size = match computed_inline_size { - MaybeAuto::Auto => { - block.get_shrink_to_fit_inline_size(available_inline_size - (inline_start_margin + - inline_end_margin)) - } + MaybeAuto::Auto => block.get_shrink_to_fit_inline_size( + available_inline_size - (inline_start_margin + inline_end_margin), + ), MaybeAuto::Specified(inline_size) => inline_size, }; @@ -3038,23 +3623,22 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { /// /// ISize has already been calculated. We now calculate the margins just /// like for non-replaced blocks. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + input: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { debug_assert!(match input.computed_inline_size { MaybeAuto::Specified(_) => true, MaybeAuto::Auto => false, }); - let (computed_inline_size, - inline_start_margin, - inline_end_margin, - available_inline_size) = - (input.computed_inline_size, - input.inline_start_margin, - input.inline_end_margin, - input.available_inline_size); + let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = ( + input.computed_inline_size, + input.inline_start_margin, + input.inline_end_margin, + input.available_inline_size, + ); // For inline-blocks, `auto` margins compute to 0. let inline_start_margin = inline_start_margin.specified_or_zero(); @@ -3063,10 +3647,9 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { // If inline-size is set to 'auto', and this is an inline block, use the // shrink to fit algorithm (see CSS 2.1 § 10.3.9) let inline_size = match computed_inline_size { - MaybeAuto::Auto => { - block.get_shrink_to_fit_inline_size(available_inline_size - (inline_start_margin + - inline_end_margin)) - } + MaybeAuto::Auto => block.get_shrink_to_fit_inline_size( + available_inline_size - (inline_start_margin + inline_end_margin), + ), MaybeAuto::Specified(inline_size) => inline_size, }; @@ -3074,14 +3657,18 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { } /// Calculate used value of inline-size just like we do for inline replaced elements. - fn initial_computed_inline_size(&self, - block: &mut BlockFlow, - parent_flow_inline_size: Au, - shared_context: &SharedStyleContext) - -> MaybeAuto { + fn initial_computed_inline_size( + &self, + block: &mut BlockFlow, + parent_flow_inline_size: Au, + shared_context: &SharedStyleContext, + ) -> MaybeAuto { let container_block_size = block.explicit_block_containing_size(shared_context); let fragment = block.fragment(); - fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, container_block_size); + fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); // For replaced block flow, the rest of the constraint solving will // take inline-size to be specified as the value computed here. MaybeAuto::Specified(fragment.content_box().size.inline) @@ -3091,23 +3678,30 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { impl ISizeAndMarginsComputer for InlineFlexItem { // Replace the default method directly to prevent recalculating and setting margins again // which has already been set by its parent. - fn compute_used_inline_size(&self, - block: &mut BlockFlow, - shared_context: &SharedStyleContext, - parent_flow_inline_size: Au) { + fn compute_used_inline_size( + &self, + block: &mut BlockFlow, + shared_context: &SharedStyleContext, + parent_flow_inline_size: Au, + ) { let container_block_size = block.explicit_block_containing_size(shared_context); - block.fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, - container_block_size); + block.fragment.assign_replaced_inline_size_if_necessary( + parent_flow_inline_size, + container_block_size, + ); } // The used inline size and margins are set by parent flex flow, do nothing here. - fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - _: &ISizeConstraintInput) - -> ISizeConstraintSolution { + fn solve_inline_size_constraints( + &self, + block: &mut BlockFlow, + _: &ISizeConstraintInput, + ) -> ISizeConstraintSolution { let fragment = block.fragment(); - ISizeConstraintSolution::new(fragment.border_box.size.inline, - fragment.margin.inline_start, - fragment.margin.inline_end) + ISizeConstraintSolution::new( + fragment.border_box.size.inline, + fragment.margin.inline_start, + fragment.margin.inline_end, + ) } } |