mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Implement min-width and max-width for non-block flows.
+ Add simple reftests. + Add reftests for float min-width and max-width.
This commit is contained in:
parent
e98c839ab0
commit
9d510a7112
12 changed files with 292 additions and 77 deletions
|
@ -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
|
||||
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
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,13 +1572,16 @@ 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,
|
||||
/// 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)
|
||||
|
@ -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 input = self.pre_computation(block, parent_flow_width, ctx);
|
||||
let containing_block_width = self.containing_block_width(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;
|
||||
|
|
|
@ -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
|
||||
|
|
24
src/test/ref/max_width_float_simple_a.html
Normal file
24
src/test/ref/max_width_float_simple_a.html
Normal file
|
@ -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>
|
22
src/test/ref/max_width_float_simple_b.html
Normal file
22
src/test/ref/max_width_float_simple_b.html
Normal file
|
@ -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>
|
24
src/test/ref/max_width_simple_a.html
Normal file
24
src/test/ref/max_width_simple_a.html
Normal file
|
@ -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>
|
22
src/test/ref/max_width_simple_b.html
Normal file
22
src/test/ref/max_width_simple_b.html
Normal file
|
@ -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>
|
25
src/test/ref/min_width_float_simple_a.html
Normal file
25
src/test/ref/min_width_float_simple_a.html
Normal file
|
@ -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>
|
22
src/test/ref/min_width_float_simple_b.html
Normal file
22
src/test/ref/min_width_float_simple_b.html
Normal file
|
@ -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>
|
24
src/test/ref/min_width_simple_a.html
Normal file
24
src/test/ref/min_width_simple_a.html
Normal file
|
@ -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>
|
22
src/test/ref/min_width_simple_b.html
Normal file
22
src/test/ref/min_width_simple_b.html
Normal file
|
@ -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>
|
23
src/test/ref/width_nonreplaced_block_simple_a.html
Normal file
23
src/test/ref/width_nonreplaced_block_simple_a.html
Normal file
|
@ -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>
|
22
src/test/ref/width_nonreplaced_block_simple_b.html
Normal file
22
src/test/ref/width_nonreplaced_block_simple_b.html
Normal file
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue