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 {
|
fn width_computer(&mut self) -> ~WidthAndMarginsComputer {
|
||||||
BlockFlow {
|
if self.is_absolutely_positioned() {
|
||||||
base: base,
|
if self.is_replaced_content() {
|
||||||
box_: None,
|
~AbsoluteReplaced as ~WidthAndMarginsComputer
|
||||||
is_root: true,
|
} else {
|
||||||
static_y_offset: Au::new(0),
|
~AbsoluteNonReplaced as ~WidthAndMarginsComputer
|
||||||
float: None
|
}
|
||||||
}
|
} else if self.is_float() {
|
||||||
}
|
if self.is_replaced_content() {
|
||||||
|
~FloatReplaced as ~WidthAndMarginsComputer
|
||||||
pub fn new_float(base: BaseFlow, float_kind: FloatKind) -> BlockFlow {
|
} else {
|
||||||
BlockFlow {
|
~FloatNonReplaced as ~WidthAndMarginsComputer
|
||||||
base: base,
|
}
|
||||||
box_: None,
|
} else {
|
||||||
is_root: false,
|
if self.is_replaced_content() {
|
||||||
static_y_offset: Au::new(0),
|
~BlockReplaced as ~WidthAndMarginsComputer
|
||||||
float: Some(~FloatedBlockInfo::new(float_kind))
|
} else {
|
||||||
|
~BlockNonReplaced as ~WidthAndMarginsComputer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1282,28 +1284,7 @@ impl Flow for BlockFlow {
|
||||||
self.base.flags_info.flags.set_inorder(false);
|
self.base.flags_info.flags.set_inorder(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let width_computer;
|
let width_computer = self.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
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
width_computer.compute_used_width(self, ctx, containing_block_width);
|
width_computer.compute_used_width(self, ctx, containing_block_width);
|
||||||
|
|
||||||
for box_ in self.box_.iter() {
|
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 {
|
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 to compute the initial inputs. For
|
||||||
/// This is called only once.
|
/// calculation involving min-width and max-width, we don't need to
|
||||||
// TODO(pradeep): Rename this to compute_inputs
|
/// recompute these.
|
||||||
fn pre_computation(&self,
|
fn compute_width_constraint_inputs(&self,
|
||||||
block: &mut BlockFlow,
|
block: &mut BlockFlow,
|
||||||
parent_flow_width: Au,
|
parent_flow_width: Au,
|
||||||
ctx: &mut LayoutContext)
|
ctx: &mut LayoutContext)
|
||||||
-> WidthConstraintInput {
|
-> WidthConstraintInput {
|
||||||
let containing_block_width = self.containing_block_width(block, parent_flow_width, ctx);
|
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);
|
let computed_width = self.initial_computed_width(block, parent_flow_width, ctx);
|
||||||
|
@ -1694,40 +1678,33 @@ trait WidthAndMarginsComputer {
|
||||||
block: &mut BlockFlow,
|
block: &mut BlockFlow,
|
||||||
ctx: &mut LayoutContext,
|
ctx: &mut LayoutContext,
|
||||||
parent_flow_width: Au) {
|
parent_flow_width: Au) {
|
||||||
// TODO(pradeep): First, get the constraint solutions. Then, do the
|
let mut input = self.compute_width_constraint_inputs(block, parent_flow_width, ctx);
|
||||||
// min-width + max-width dance. THEN, set the width in the Box.
|
|
||||||
|
|
||||||
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_width_constraint_solutions(block, solution);
|
||||||
self.set_flow_x_coord_if_necessary(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.
|
/// 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 AbsoluteNonReplaced;
|
||||||
struct AbsoluteReplaced;
|
struct AbsoluteReplaced;
|
||||||
struct BlockNonReplaced;
|
struct BlockNonReplaced;
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
== object_element_a.html object_element_b.html
|
== object_element_a.html object_element_b.html
|
||||||
== height_compute_reset.html height_compute.html
|
== height_compute_reset.html height_compute.html
|
||||||
== width_nonreplaced_block_simple_a.html width_nonreplaced_block_simple_b.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
|
# Positioning tests
|
||||||
== position_abs_cb_with_non_cb_kid_a.html position_abs_cb_with_non_cb_kid_b.html
|
== 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
|
== 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