aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorS Pradeep Kumar <gohanpra@gmail.com>2014-03-07 19:08:31 +0900
committerS Pradeep Kumar <gohanpra@gmail.com>2014-03-10 15:22:15 +0900
commit9d510a7112c9ecafe4e20ecdbb4e8653a82d772e (patch)
treea5329999bced7dcd777eb57f8d60cab0b76bf4e0
parente98c839ab07c43cefd699e0bd60e9568039833d5 (diff)
downloadservo-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.rs135
-rw-r--r--src/test/ref/basic.list4
-rw-r--r--src/test/ref/max_width_float_simple_a.html24
-rw-r--r--src/test/ref/max_width_float_simple_b.html22
-rw-r--r--src/test/ref/max_width_simple_a.html24
-rw-r--r--src/test/ref/max_width_simple_b.html22
-rw-r--r--src/test/ref/min_width_float_simple_a.html25
-rw-r--r--src/test/ref/min_width_float_simple_b.html22
-rw-r--r--src/test/ref/min_width_simple_a.html24
-rw-r--r--src/test/ref/min_width_simple_b.html22
-rw-r--r--src/test/ref/width_nonreplaced_block_simple_a.html23
-rw-r--r--src/test/ref/width_nonreplaced_block_simple_b.html22
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>