diff options
author | S Pradeep Kumar <gohanpra@gmail.com> | 2014-03-07 19:08:31 +0900 |
---|---|---|
committer | S Pradeep Kumar <gohanpra@gmail.com> | 2014-03-10 15:22:15 +0900 |
commit | 9d510a7112c9ecafe4e20ecdbb4e8653a82d772e (patch) | |
tree | a5329999bced7dcd777eb57f8d60cab0b76bf4e0 | |
parent | e98c839ab07c43cefd699e0bd60e9568039833d5 (diff) | |
download | servo-9d510a7112c9ecafe4e20ecdbb4e8653a82d772e.tar.gz servo-9d510a7112c9ecafe4e20ecdbb4e8653a82d772e.zip |
Implement min-width and max-width for non-block flows.
+ Add simple reftests.
+ Add reftests for float min-width and max-width.
-rw-r--r-- | src/components/main/layout/block.rs | 135 | ||||
-rw-r--r-- | src/test/ref/basic.list | 4 | ||||
-rw-r--r-- | src/test/ref/max_width_float_simple_a.html | 24 | ||||
-rw-r--r-- | src/test/ref/max_width_float_simple_b.html | 22 | ||||
-rw-r--r-- | src/test/ref/max_width_simple_a.html | 24 | ||||
-rw-r--r-- | src/test/ref/max_width_simple_b.html | 22 | ||||
-rw-r--r-- | src/test/ref/min_width_float_simple_a.html | 25 | ||||
-rw-r--r-- | src/test/ref/min_width_float_simple_b.html | 22 | ||||
-rw-r--r-- | src/test/ref/min_width_simple_a.html | 24 | ||||
-rw-r--r-- | src/test/ref/min_width_simple_b.html | 22 | ||||
-rw-r--r-- | src/test/ref/width_nonreplaced_block_simple_a.html | 23 | ||||
-rw-r--r-- | src/test/ref/width_nonreplaced_block_simple_b.html | 22 |
12 files changed, 292 insertions, 77 deletions
diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index 8bf3089b765..70889db3ab9 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -364,23 +364,25 @@ impl BlockFlow { } } - pub fn new_root(base: BaseFlow) -> BlockFlow { - BlockFlow { - base: base, - box_: None, - is_root: true, - static_y_offset: Au::new(0), - float: None - } - } - - pub fn new_float(base: BaseFlow, float_kind: FloatKind) -> BlockFlow { - BlockFlow { - base: base, - box_: None, - is_root: false, - static_y_offset: Au::new(0), - float: Some(~FloatedBlockInfo::new(float_kind)) + fn width_computer(&mut self) -> ~WidthAndMarginsComputer { + if self.is_absolutely_positioned() { + if self.is_replaced_content() { + ~AbsoluteReplaced as ~WidthAndMarginsComputer + } else { + ~AbsoluteNonReplaced as ~WidthAndMarginsComputer + } + } else if self.is_float() { + if self.is_replaced_content() { + ~FloatReplaced as ~WidthAndMarginsComputer + } else { + ~FloatNonReplaced as ~WidthAndMarginsComputer + } + } else { + if self.is_replaced_content() { + ~BlockReplaced as ~WidthAndMarginsComputer + } else { + ~BlockNonReplaced as ~WidthAndMarginsComputer + } } } @@ -1282,28 +1284,7 @@ impl Flow for BlockFlow { self.base.flags_info.flags.set_inorder(false); } - let width_computer; - // TODO(pradeep): Extract this into a method. - width_computer = if self.is_absolutely_positioned() { - if self.is_replaced_content() { - &AbsoluteReplaced as &WidthAndMarginsComputer - } else { - &AbsoluteNonReplaced as &WidthAndMarginsComputer - } - } else if self.is_float() { - if self.is_replaced_content() { - &FloatReplaced as &WidthAndMarginsComputer - } else { - &FloatNonReplaced as &WidthAndMarginsComputer - } - } else { - if self.is_replaced_content() { - &BlockReplaced as &WidthAndMarginsComputer - } else { - &BlockNonReplaced as &WidthAndMarginsComputer - } - }; - + let width_computer = self.width_computer(); width_computer.compute_used_width(self, ctx, containing_block_width); for box_ in self.box_.iter() { @@ -1591,16 +1572,19 @@ impl WidthConstraintSolution { } } +// Trait to encapsulate the Width and Margin calculation. +// +// CSS Section 10.3 trait WidthAndMarginsComputer { - /// Any pre-computation to be done for widths. + /// Compute the inputs for the Width constraint equation. /// - /// Compute and return the necessary input values from the box's style. - /// This is called only once. - // TODO(pradeep): Rename this to compute_inputs - fn pre_computation(&self, - block: &mut BlockFlow, - parent_flow_width: Au, - ctx: &mut LayoutContext) + /// This is called only once to compute the initial inputs. For + /// calculation involving min-width and max-width, we don't need to + /// recompute these. + fn compute_width_constraint_inputs(&self, + block: &mut BlockFlow, + parent_flow_width: Au, + ctx: &mut LayoutContext) -> WidthConstraintInput { let containing_block_width = self.containing_block_width(block, parent_flow_width, ctx); let computed_width = self.initial_computed_width(block, parent_flow_width, ctx); @@ -1694,40 +1678,33 @@ trait WidthAndMarginsComputer { block: &mut BlockFlow, ctx: &mut LayoutContext, parent_flow_width: Au) { - // TODO(pradeep): First, get the constraint solutions. Then, do the - // min-width + max-width dance. THEN, set the width in the Box. + let mut input = self.compute_width_constraint_inputs(block, parent_flow_width, ctx); + + let containing_block_width = self.containing_block_width(block, parent_flow_width, ctx); - let input = self.pre_computation(block, parent_flow_width, ctx); + let mut solution = self.solve_width_constraints(block, input); + + // If the tentative used width is greater than 'max-width', width should be recalculated, + // but this time using the computed value of 'max-width' as the computed value for 'width'. + match specified_or_none(block.box_().style().Box.get().max_width, containing_block_width) { + Some(max_width) if max_width < solution.width => { + input.computed_width = Specified(max_width); + solution = self.solve_width_constraints(block, input); + } + _ => {} + } + + // If the resulting width is smaller than 'min-width', width should be recalculated, + // but this time using the value of 'min-width' as the computed value for 'width'. + let computed_min_width = specified(block.box_().style().Box.get().min_width, + containing_block_width); + if computed_min_width > solution.width { + input.computed_width = Specified(computed_min_width); + solution = self.solve_width_constraints(block, input); + } - let solution = self.solve_width_constraints(block, input); self.set_width_constraint_solutions(block, solution); self.set_flow_x_coord_if_necessary(block, solution); - - // // If the tentative used width is greater than 'max-width', width should be recalculated, - // // but this time using the computed value of 'max-width' as the computed value for 'width'. - // let (width, margin_left, margin_right) = { - // match specified_or_none(style.Box.get().max_width, containing_block_width) { - // Some(value) if value < width => block.compute_horiz(Specified(value), - // maybe_margin_left, - // maybe_margin_right, - // available_width), - // _ => (width, margin_left, margin_right) - // } - // }; - - // // If the resulting width is smaller than 'min-width', width should be recalculated, - // // but this time using the value of 'min-width' as the computed value for 'width'. - // let (width, margin_left, margin_right) = { - // let computed_min_width = specified(style.Box.get().min_width, containing_block_width); - // if computed_min_width > width { - // block.compute_horiz(Specified(computed_min_width), - // maybe_margin_left, - // maybe_margin_right, - // available_width) - // } else { - // (width, margin_left, margin_right) - // } - // }; } /// Computes left and right margins and width. @@ -1800,6 +1777,10 @@ trait WidthAndMarginsComputer { } } +/// The different types of Blocks. +/// +/// They mainly differ in the way width and heights and margins are calculated +/// for them. struct AbsoluteNonReplaced; struct AbsoluteReplaced; struct BlockNonReplaced; diff --git a/src/test/ref/basic.list b/src/test/ref/basic.list index 223fe3bfaf6..d883d036054 100644 --- a/src/test/ref/basic.list +++ b/src/test/ref/basic.list @@ -35,6 +35,10 @@ == object_element_a.html object_element_b.html == height_compute_reset.html height_compute.html == width_nonreplaced_block_simple_a.html width_nonreplaced_block_simple_b.html +== max_width_float_simple_a.html max_width_float_simple_b.html +== max_width_simple_a.html max_width_simple_b.html +== min_width_float_simple_a.html min_width_float_simple_b.html +== min_width_simple_a.html min_width_simple_b.html # Positioning tests == position_abs_cb_with_non_cb_kid_a.html position_abs_cb_with_non_cb_kid_b.html == position_abs_height_width_a.html position_abs_height_width_b.html diff --git a/src/test/ref/max_width_float_simple_a.html b/src/test/ref/max_width_float_simple_a.html new file mode 100644 index 00000000000..8ce2c4216ce --- /dev/null +++ b/src/test/ref/max_width_float_simple_a.html @@ -0,0 +1,24 @@ +<html> + <head> + <style> + #first { + width: 100px; + height: 100px; + border: solid 1px; + } + #float { + float: left; + height: 50px; + width: 50px; + max-width: 40px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="float"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/max_width_float_simple_b.html b/src/test/ref/max_width_float_simple_b.html new file mode 100644 index 00000000000..4fe2cd7165a --- /dev/null +++ b/src/test/ref/max_width_float_simple_b.html @@ -0,0 +1,22 @@ +<html> + <head> + <style> + #first { + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 40px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/max_width_simple_a.html b/src/test/ref/max_width_simple_a.html new file mode 100644 index 00000000000..e8bfb8555c5 --- /dev/null +++ b/src/test/ref/max_width_simple_a.html @@ -0,0 +1,24 @@ +<html> + <head> + <style> + #first { + position: relative; + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 50%; + max-width: 40px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/max_width_simple_b.html b/src/test/ref/max_width_simple_b.html new file mode 100644 index 00000000000..4fe2cd7165a --- /dev/null +++ b/src/test/ref/max_width_simple_b.html @@ -0,0 +1,22 @@ +<html> + <head> + <style> + #first { + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 40px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/min_width_float_simple_a.html b/src/test/ref/min_width_float_simple_a.html new file mode 100644 index 00000000000..dea5d19cee7 --- /dev/null +++ b/src/test/ref/min_width_float_simple_a.html @@ -0,0 +1,25 @@ +<html> + <head> + <style> + #first { + position: relative; + width: 100px; + height: 100px; + border: solid 1px; + } + #float { + float: left; + height: 50px; + width: 50%; + min-width: 60px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="float"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/min_width_float_simple_b.html b/src/test/ref/min_width_float_simple_b.html new file mode 100644 index 00000000000..e155bab183f --- /dev/null +++ b/src/test/ref/min_width_float_simple_b.html @@ -0,0 +1,22 @@ +<html> + <head> + <style> + #first { + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 60px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/min_width_simple_a.html b/src/test/ref/min_width_simple_a.html new file mode 100644 index 00000000000..203281f6166 --- /dev/null +++ b/src/test/ref/min_width_simple_a.html @@ -0,0 +1,24 @@ +<html> + <head> + <style> + #first { + position: relative; + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 50%; + min-width: 60px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/min_width_simple_b.html b/src/test/ref/min_width_simple_b.html new file mode 100644 index 00000000000..e155bab183f --- /dev/null +++ b/src/test/ref/min_width_simple_b.html @@ -0,0 +1,22 @@ +<html> + <head> + <style> + #first { + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 60px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/width_nonreplaced_block_simple_a.html b/src/test/ref/width_nonreplaced_block_simple_a.html new file mode 100644 index 00000000000..f06f040946e --- /dev/null +++ b/src/test/ref/width_nonreplaced_block_simple_a.html @@ -0,0 +1,23 @@ +<html> + <head> + <style> + #first { + position: relative; + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 50%; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> diff --git a/src/test/ref/width_nonreplaced_block_simple_b.html b/src/test/ref/width_nonreplaced_block_simple_b.html new file mode 100644 index 00000000000..8f1282a01d6 --- /dev/null +++ b/src/test/ref/width_nonreplaced_block_simple_b.html @@ -0,0 +1,22 @@ +<html> + <head> + <style> + #first { + width: 100px; + height: 100px; + border: solid 1px; + } + #block { + height: 50px; + width: 50px; + background: green; + } + </style> + </head> + <body> + <div id="first"> + <div id="block"> + </div> + </div> + </body> +</html> |