Make the interface to calculated styles a little nicer

This commit is contained in:
Brian Anderson 2012-11-04 03:07:43 -08:00
parent 735ce3ba5a
commit 37be37cbb1
5 changed files with 57 additions and 44 deletions

View file

@ -31,6 +31,6 @@ impl Node : MatchMethods {
node: self
};
let style = select_ctx.select_style(&self, &select_handler);
self.set_style(move style);
self.set_css_select_results(move style);
}
}

View file

@ -13,80 +13,88 @@ use newcss::values::{CSSMargin, CSSMarginLength};
use newcss::values::{CSSBorderWidth, CSSBorderWidthLength};
use newcss::computed::ComputedStyle;
pub trait ComputeStyles {
fn compute_background_color(&self) -> Color;
fn compute_margin_top(&self) -> CSSMargin;
fn compute_margin_right(&self) -> CSSMargin;
fn compute_margin_bottom(&self) -> CSSMargin;
fn compute_margin_left(&self) -> CSSMargin;
fn compute_border_top_width(&self) -> CSSBorderWidth;
fn compute_border_right_width(&self) -> CSSBorderWidth;
fn compute_border_bottom_width(&self) -> CSSBorderWidth;
fn compute_border_left_width(&self) -> CSSBorderWidth;
fn compute_border_top_color(&self) -> Color;
fn compute_border_right_color(&self) -> Color;
fn compute_border_bottom_color(&self) -> Color;
fn compute_border_left_color(&self) -> Color;
/// Node mixin providing `style` method that returns a `NodeStyle`
trait StyledNode {
fn style(&self) -> NodeStyle/&self;
}
impl Node: ComputeStyles {
fn compute_background_color(&self) -> Color {
impl Node: StyledNode {
fn style(&self) -> NodeStyle/&self {
NodeStyle::new(self)
}
}
/// Provides getters for calculated node styles
pub struct NodeStyle {
priv node: &Node
}
impl NodeStyle {
static fn new(node: &r/Node) -> NodeStyle/&r {
NodeStyle {
node: node
}
}
fn background_color(&self) -> Color {
resolve(self, rgba(0, 0, 0, 0.0), |cs| cs.background_color() )
}
fn compute_margin_top(&self) -> CSSMargin {
fn margin_top(&self) -> CSSMargin {
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_top() )
}
fn compute_margin_right(&self) -> CSSMargin {
fn margin_right(&self) -> CSSMargin {
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_right() )
}
fn compute_margin_bottom(&self) -> CSSMargin {
fn margin_bottom(&self) -> CSSMargin {
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_bottom() )
}
fn compute_margin_left(&self) -> CSSMargin {
fn margin_left(&self) -> CSSMargin {
resolve(self, CSSMarginLength(Px(0.0)), |cs| cs.margin_left() )
}
fn compute_border_top_width(&self) -> CSSBorderWidth {
fn border_top_width(&self) -> CSSBorderWidth {
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_top_width() )
}
fn compute_border_right_width(&self) -> CSSBorderWidth {
fn border_right_width(&self) -> CSSBorderWidth {
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_right_width() )
}
fn compute_border_bottom_width(&self) -> CSSBorderWidth {
fn border_bottom_width(&self) -> CSSBorderWidth {
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_bottom_width() )
}
fn compute_border_left_width(&self) -> CSSBorderWidth {
fn border_left_width(&self) -> CSSBorderWidth {
resolve(self, CSSBorderWidthLength(Px(0.0)), |cs| cs.border_left_width() )
}
fn compute_border_top_color(&self) -> Color {
fn border_top_color(&self) -> Color {
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_top_color() )
}
fn compute_border_right_color(&self) -> Color {
fn border_right_color(&self) -> Color {
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_right_color() )
}
fn compute_border_bottom_color(&self) -> Color {
fn border_bottom_color(&self) -> Color {
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_bottom_color() )
}
fn compute_border_left_color(&self) -> Color {
fn border_left_color(&self) -> Color {
resolve(self, rgba(255, 255, 255, 0.0), |cs| cs.border_left_color() )
}
}
fn resolve<T>(node: &Node, default: T, get: &fn(cs: ComputedStyle) -> CSSValue<T>) -> T {
let style = node.get_style();
let computed = style.computed_style();
fn resolve<T>(node_style: &NodeStyle, default: T, get: &fn(cs: ComputedStyle) -> CSSValue<T>) -> T {
let node = node_style.node;
let select_res = node.get_css_select_results();
let computed = select_res.computed_style();
let value = get(computed);
match move value {
Inherit => /* FIXME: need inheritance */ move default,

View file

@ -3,8 +3,8 @@ use newcss::select::SelectResults;
use std::cell::Cell;
trait NodeUtil {
fn get_style() -> &self/SelectResults;
fn set_style(decl : SelectResults);
fn get_css_select_results() -> &self/SelectResults;
fn set_css_select_results(decl : SelectResults);
}
impl Node: NodeUtil {
@ -15,7 +15,7 @@ impl Node: NodeUtil {
* FIXME: This isn't completely memory safe since the style is
* stored in a box that can be overwritten
*/
fn get_style() -> &self/SelectResults {
fn get_css_select_results() -> &self/SelectResults {
if !self.has_aux() {
fail ~"style() called on a node without aux data!";
}
@ -30,7 +30,7 @@ impl Node: NodeUtil {
/**
Update the computed style of an HTML element with a style specified by CSS.
*/
fn set_style(decl : SelectResults) {
fn set_css_select_results(decl : SelectResults) {
let decl = Cell(move decl);
do self.aux |data| {
data.style = Some(decl.take())

View file

@ -8,7 +8,7 @@ use au::Au;
use core::dvec::DVec;
use core::to_str::ToStr;
use core::rand;
use css::compute::ComputeStyles;
use css::node_style::{NodeStyle, StyledNode};
use newcss::units::{BoxSizing, Length, Px};
use newcss::values::{CSSDisplay, Specified, CSSBackgroundColorColor, CSSBackgroundColorTransparent};
use newcss::values::{CSSBorderColor, CSSPositionAbsolute};
@ -365,6 +365,11 @@ impl RenderBox : RenderBoxMethods {
self.content_box()
}
fn style(&self) -> NodeStyle/&self {
let d: &self/RenderBoxData = self.d();
d.node.style()
}
// TODO: to implement stacking contexts correctly, we need to
// create a set of display lists, one per each layer of a stacking
// context. (CSS 2.1, Section 9.9.1). Each box is passed the list
@ -430,17 +435,17 @@ impl RenderBox : RenderBoxMethods {
fn add_bgcolor_to_list(list: &mut DisplayList, abs_bounds: &Rect<Au>) {
use std::cmp::FuzzyEq;
let bgcolor = self.d().node.compute_background_color();
let bgcolor = self.style().background_color();
if !bgcolor.alpha.fuzzy_eq(&0.0) {
list.append_item(~DisplayItem::new_SolidColor(abs_bounds, bgcolor.to_gfx_color()));
}
}
fn add_border_to_list(list: &mut DisplayList, abs_bounds: &Rect<Au>) {
let top_width = self.d().node.compute_border_top_width();
let right_width = self.d().node.compute_border_right_width();
let bottom_width = self.d().node.compute_border_bottom_width();
let left_width = self.d().node.compute_border_left_width();
let top_width = self.style().border_top_width();
let right_width = self.style().border_right_width();
let bottom_width = self.style().border_bottom_width();
let left_width = self.style().border_left_width();
match (top_width, right_width, bottom_width, left_width) {
(CSSBorderWidthLength(Px(top)),
@ -467,7 +472,7 @@ impl RenderBox : RenderBoxMethods {
}
};
let top_color = self.d().node.compute_border_top_color();
let top_color = self.style().border_top_color();
let color = top_color.to_gfx_color(); // FIXME
list.append_item(~DisplayItem::new_Border(&bounds, border_width, color));

View file

@ -44,8 +44,8 @@ pub mod content {
}
pub mod css {
pub mod node_style;
pub mod matching;
pub mod compute;
priv mod select_handler;
priv mod node_util;
priv mod node_void_ptr;