diff options
-rw-r--r-- | components/layout/block.rs | 116 | ||||
-rw-r--r-- | tests/ref/basic.list | 2 | ||||
-rw-r--r-- | tests/ref/inline_block_margin_auto_a.html | 20 | ||||
-rw-r--r-- | tests/ref/inline_block_margin_auto_ref.html | 20 | ||||
-rw-r--r-- | tests/ref/inline_block_margin_auto_zero_a.html | 20 | ||||
-rw-r--r-- | tests/ref/inline_block_margin_auto_zero_ref.html | 24 | ||||
-rw-r--r-- | tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-width-001.htm.ini | 3 |
7 files changed, 196 insertions, 9 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index 68b149b5c5d..a9532d6ab1a 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -505,6 +505,8 @@ pub enum BlockType { AbsoluteNonReplaced, FloatReplaced, FloatNonReplaced, + InlineBlockReplaced, + InlineBlockNonReplaced, } #[derive(Clone, PartialEq)] @@ -614,6 +616,12 @@ impl BlockFlow { } else { BlockType::FloatNonReplaced } + } else if self.is_inline_block() { + if self.is_replaced_content() { + BlockType::InlineBlockReplaced + } else { + BlockType::InlineBlockNonReplaced + } } else { if self.is_replaced_content() { BlockType::Replaced @@ -680,6 +688,18 @@ impl BlockFlow { layout_context, containing_block_inline_size); } + BlockType::InlineBlockReplaced => { + let inline_size_computer = InlineBlockReplaced; + inline_size_computer.compute_used_inline_size(self, + layout_context, + containing_block_inline_size); + } + BlockType::InlineBlockNonReplaced => { + let inline_size_computer = InlineBlockNonReplaced; + inline_size_computer.compute_used_inline_size(self, + layout_context, + containing_block_inline_size); + } BlockType::Replaced => { let inline_size_computer = BlockReplaced; inline_size_computer.compute_used_inline_size(self, @@ -2481,12 +2501,6 @@ pub trait ISizeAndMarginsComputer { } }; - // 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) - if computed_inline_size == MaybeAuto::Auto && block.is_inline_block() { - inline_size = block.get_shrink_to_fit_inline_size(inline_size); - } - ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin) } } @@ -2501,6 +2515,8 @@ pub struct BlockNonReplaced; pub struct BlockReplaced; pub struct FloatNonReplaced; pub struct FloatReplaced; +pub struct InlineBlockNonReplaced; +pub struct InlineBlockReplaced; impl ISizeAndMarginsComputer for AbsoluteNonReplaced { /// Solve the horizontal constraint equation for absolute non-replaced elements. @@ -2899,3 +2915,91 @@ impl ISizeAndMarginsComputer for FloatReplaced { MaybeAuto::Specified(fragment.content_inline_size()) } } + +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 (mut 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(); + let inline_end_margin = inline_end_margin.specified_or_zero(); + + // 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::Specified(inline_size) => inline_size, + }; + + ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin) + } +} + +impl ISizeAndMarginsComputer for InlineBlockReplaced { + /// Compute inline-start and inline-end margins and inline-size. + /// + /// 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 { + debug_assert!(match input.computed_inline_size { + MaybeAuto::Specified(_) => true, + MaybeAuto::Auto => false, + }); + + let (mut 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(); + let inline_end_margin = inline_end_margin.specified_or_zero(); + + // 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::Specified(inline_size) => inline_size, + }; + + ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin) + } + + /// 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, + _: &LayoutContext) + -> MaybeAuto { + let fragment = block.fragment(); + fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_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_inline_size()) + } +} + diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 6d6cf789c31..b25d3e9efa8 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -168,6 +168,8 @@ prefs:"layout.writing-mode.enabled" == iframe/size_attributes_vertical_writing_m == inline_block_border_intrinsic_size_a.html inline_block_border_intrinsic_size_ref.html == inline_block_img_a.html inline_block_img_ref.html == inline_block_margin_a.html inline_block_margin_ref.html +== inline_block_margin_auto_a.html inline_block_margin_auto_ref.html +== inline_block_margin_auto_zero_a.html inline_block_margin_auto_zero_ref.html == inline_block_min_width.html inline_block_min_width_ref.html == inline_block_overflow.html inline_block_overflow_ref.html == inline_block_overflow_hidden_a.html inline_block_overflow_hidden_ref.html diff --git a/tests/ref/inline_block_margin_auto_a.html b/tests/ref/inline_block_margin_auto_a.html new file mode 100644 index 00000000000..3fa23c34563 --- /dev/null +++ b/tests/ref/inline_block_margin_auto_a.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<style> +html, body { + margin: 0; +} +#a { + display: block; + background: lime; + text-align: center; + width: 96px; +} +#b { + background: gold; + display: inline-block; + margin: 0 auto; + padding: 16px 16px; +} +</style> +<div id=a><div id=b></div> + diff --git a/tests/ref/inline_block_margin_auto_ref.html b/tests/ref/inline_block_margin_auto_ref.html new file mode 100644 index 00000000000..1ab56dd83fb --- /dev/null +++ b/tests/ref/inline_block_margin_auto_ref.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<style> +html, body { + margin: 0; +} +#a { + display: block; + background: lime; + text-align: center; + width: 96px; +} +#b { + background: gold; + display: inline-block; + margin: 0 32px 0 32px; + padding: 16px 16px; +} +</style> +<div id=a><div id=b></div> + diff --git a/tests/ref/inline_block_margin_auto_zero_a.html b/tests/ref/inline_block_margin_auto_zero_a.html new file mode 100644 index 00000000000..e9a0ec4fb29 --- /dev/null +++ b/tests/ref/inline_block_margin_auto_zero_a.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<style> +html, body { + margin: 0; +} +section { + width: 300px; + height: 100px; + background: blue; +} +nav { + display: inline-block; + width: 100px; + height: 100px; + margin: 0 auto; + background: gold; +} +</style> +<section><nav></nav></section> + diff --git a/tests/ref/inline_block_margin_auto_zero_ref.html b/tests/ref/inline_block_margin_auto_zero_ref.html new file mode 100644 index 00000000000..ad02e27d2fd --- /dev/null +++ b/tests/ref/inline_block_margin_auto_zero_ref.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<style> +html, body { + margin: 0; +} +section { + position: absolute; + width: 100px; + height: 100px; + top: 0; + left: 0; + background: gold; +} +nav { + position: absolute; + width: 200px; + height: 100px; + top: 0; + left: 100px; + background: blue; +} +</style> +<section></section><nav></nav> + diff --git a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-width-001.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-width-001.htm.ini deleted file mode 100644 index 3924d417aba..00000000000 --- a/tests/wpt/metadata-css/css21_dev/html4/inline-block-replaced-width-001.htm.ini +++ /dev/null @@ -1,3 +0,0 @@ -[inline-block-replaced-width-001.htm] - type: reftest - expected: FAIL |