Added the ability to specify width by css

This commit is contained in:
Margaret Meyerhofer 2012-08-10 17:02:23 -07:00
parent 95d0998149
commit 2eb6f39be2
6 changed files with 87 additions and 13 deletions

View file

@ -46,7 +46,7 @@ impl @Box : BlockLayoutMethods {
let width = match self.appearance.width { let width = match self.appearance.width {
Px(p) => px_to_au(p.to_int()), Px(p) => px_to_au(p.to_int()),
Auto => self.bounds.size.width, // Do nothing here, width was set by top-down pass Auto => self.bounds.size.width, // Do nothing here, width was set by top-down pass
_ => fail ~"inhereit_height failed, width is neither a Px or auto" _ => fail ~"inhereit_width failed, width is neither a Px or auto"
}; };
self.bounds.size = Size2D(width, height); self.bounds.size = Size2D(width, height);

View file

@ -2,7 +2,7 @@
import dom::base::{ElementData, HTMLDivElement, HTMLImageElement, Element, Text, Node}; import dom::base::{ElementData, HTMLDivElement, HTMLImageElement, Element, Text, Node};
import dom::style::{DisplayType, DisBlock, DisInline, DisNone}; import dom::style::{DisplayType, DisBlock, DisInline, DisNone};
import gfx::geometry; import gfx::geometry::zero_size_au;
import layout::base::{Appearance, BTree, BlockBox, Box, BoxKind, InlineBox, IntrinsicBox, NTree}; import layout::base::{Appearance, BTree, BlockBox, Box, BoxKind, InlineBox, IntrinsicBox, NTree};
import layout::base::{TextBoxKind}; import layout::base::{TextBoxKind};
import layout::text::TextBox; import layout::text::TextBox;
@ -157,14 +157,21 @@ impl Node : PrivBoxBuilder {
"] "]
fn determine_box_kind() -> BoxKind { fn determine_box_kind() -> BoxKind {
match self.read(|n| copy n.kind) { match self.read(|n| copy n.kind) {
~Text(string) => TextBoxKind(@TextBox(copy string)), ~Text(string) => TextBoxKind(@TextBox(copy string)),
~Element(element) => { ~Element(element) => {
match *element.kind { match (copy *element.kind, self.get_specified_style().display_type) {
HTMLDivElement => BlockBox, (HTMLImageElement({size}), _) => IntrinsicBox(@size),
HTMLImageElement({size}) => IntrinsicBox(@size), (_, some(DisBlock)) => BlockBox,
UnknownElement => InlineBox (_, some(DisInline)) => InlineBox,
(_, some(DisNone)) => {
// TODO: don't have a box here at all?
IntrinsicBox(@zero_size_au())
}
(_, none) => {
fail ~"The specified display style should be a default instead of none"
}
}
} }
}
} }
} }
} }

View file

@ -1,11 +1,13 @@
#[doc="Inline layout."] #[doc="Inline layout."]
import base::{Box, InlineBox, BTree};
import dom::rcu; import dom::rcu;
import dom::style::{Auto, Px};
import geom::point::Point2D; import geom::point::Point2D;
import geom::size::Size2D; import geom::size::Size2D;
import gfx::geometry::au; import gfx::geometry::{au, px_to_au};
import num::num;
import util::tree; import util::tree;
import base::{Box, InlineBox, BTree};
trait InlineLayout { trait InlineLayout {
fn reflow_inline(); fn reflow_inline();
@ -31,9 +33,20 @@ impl @Box : InlineLayout {
current_height = int::max(current_height, *kid.bounds.size.height); current_height = int::max(current_height, *kid.bounds.size.height);
} }
let height = match self.appearance.height {
Px(p) => px_to_au(p.to_int()),
Auto => au(current_height),
_ => fail ~"inhereit_height failed, height is neither a Px or auto"
};
let width = match self.appearance.width {
Px(p) => px_to_au(p.to_int()),
Auto => au(int::max(x, *self.bounds.size.width)),
_ => fail ~"inhereit_width failed, width is neither a Px or auto"
};
// The maximum available width should have been set in the top-down pass // The maximum available width should have been set in the top-down pass
self.bounds.size = Size2D(au(int::max(x, *self.bounds.size.width)), self.bounds.size = Size2D(width, height);
au(current_height));
#debug["reflow_inline size=%?", copy self.bounds]; #debug["reflow_inline size=%?", copy self.bounds];
} }

View file

@ -18,6 +18,7 @@ trait ApplyStyleBoxMethods {
fn inheritance_wrapper(box : @Box) { fn inheritance_wrapper(box : @Box) {
box.apply_style(); box.apply_style();
inhereit_height(box); inhereit_height(box);
inhereit_width(box);
} }
#[doc="Compute the specified height of a layout box based on it's css specification and its #[doc="Compute the specified height of a layout box based on it's css specification and its
@ -50,6 +51,36 @@ fn inhereit_height(box : @Box) {
} }
} }
#[doc="Compute the specified width of a layout box based on it's css specification and its
parent's width."]
fn inhereit_width(box : @Box) {
let style = box.node.get_specified_style();
box.appearance.width = match style.width {
none => Auto,
some(h) => match h {
Auto | Px(*) => h,
Pt(*) => PtToPx(h),
Mm(*) => MmToPx(h),
Percent(em) => {
match box.tree.parent {
none => Auto,
some(parent) => {
match parent.appearance.width {
//This is a poorly constrained case, so we ignore the percentage
Auto => Auto,
Px(f) => Px(em*f/100.0),
Percent(*) | Mm(*) | Pt(*) => {
fail ~"failed inheriting widths, parent should only be Px or Auto"
}
}
}
}
}
}
}
}
impl @Box : ApplyStyleBoxMethods { impl @Box : ApplyStyleBoxMethods {
fn apply_css_style() { fn apply_css_style() {
top_down_traversal(self, inheritance_wrapper); top_down_traversal(self, inheritance_wrapper);

View file

@ -0,0 +1,13 @@
<head>
<link rel="stylesheet" href="height_width.css" />
</head>
<body>
<div class="start">
<div class="whole"></div>
<div class="half"></div>
<div class="quarter"></div>
<div class="eighth"></div>
<div class="sixteenth"></div>
<div class="thirtysecond"></div>
</div>
</body>

10
src/test/height_width.css Normal file
View file

@ -0,0 +1,10 @@
div {display : inline}
div div {width : 120px}
.start {background-color : gray; height : 500px}
.whole {background-color : red; height : 100%}
.half {background-color : rgb(250, 125, 0); height : 50%}
.quarter {background-color : yellow; height : 25%}
.eighth {background-color : green; height : 12.5%}
.sixteenth {background-color : blue; height : 6.25%}
.thirtysecond {background-color : purple; height : 3.125%}