Create a css module and divide into values, styles, and resolve things.

This commit is contained in:
Brian J. Burg 2012-09-06 12:32:09 -07:00
parent c326c7880d
commit e1bcdc509a
18 changed files with 81 additions and 78 deletions

View file

@ -14,14 +14,14 @@ import io::{read_whole_file, println};
import dom::base::{Document, Node, NodeScope, Window, define_bindings};
import dom::event::{Event, ResizeEvent, ReflowEvent};
import dom::style;
import dom::style::Stylesheet;
import gfx::compositor::Compositor;
import parser::html_lexer::spawn_html_lexer_task;
import parser::html_builder::build_dom;
import layout::layout_task;
import layout_task::{LayoutTask, BuildMsg};
import css::styles::Stylesheet;
import jsrt = js::rust::rt;
import js::rust::{cx, methods};
import js::global::{global_class, debug_fns};

View file

@ -1,14 +1,15 @@
#[doc="Applies the appropriate CSS style to boxes."]
import dom::base::{Element, HTMLImageElement, Node};
import dom::style::{Percent, Mm, Pt, Px, Auto, PtToPx, MmToPx};
import gfx::geometry::au_to_px;
import base::{Box, BTree, NTree, LayoutData, SpecifiedStyle, ImageHolder,
import layout::base::{Box, BTree, NTree, LayoutData, SpecifiedStyle, ImageHolder,
BlockBox, InlineBox, IntrinsicBox, TextBox};
import traverse::{top_down_traversal};
import layout::traverse::{top_down_traversal};
import std::net::url::Url;
import resource::image_cache_task::ImageCacheTask;
import css::values::{Percent, Mm, Pt, Px, Auto, PtToPx, MmToPx};
struct StyleApplicator {
box: @Box;
doc_url: &Url;

View file

@ -1,12 +1,13 @@
#[doc="Performs CSS selector matching."]
import base::{LayoutData};
import dom::base::{LayoutData};
import dom::base;
import base::{ElementData, Node, Text};
import dom::style::{Selector, StyleDeclaration, FontSize, Display, TextColor, BackgroundColor,
import values::{Selector, StyleDeclaration, FontSize, Display, TextColor, BackgroundColor,
Stylesheet, Element, Child, Descendant, Sibling, Attr, Exact, Exists, Includes,
StartsWith, Width, Height};
import style::{SpecifiedStyle};
import styles::{SpecifiedStyle};
#[doc="Check if a CSS attribute matches the attribute of an HTML element."]
fn attrs_match(attr: Attr, elmt: ElementData) -> bool {

View file

@ -2,12 +2,13 @@
import std::arc::{ARC, get, clone};
import dom::style::{DisplayType, DisBlock, DisInline, DisNone, Stylesheet, Unit, Auto};
import css::values::{DisplayType, DisBlock, DisInline, DisNone, Unit, Auto};
import css::values::Stylesheet;
import dom::base::{HTMLDivElement, HTMLHeadElement, HTMLImageElement, UnknownElement, HTMLScriptElement};
import dom::base::{Comment, Doctype, Element, Node, NodeKind, Text};
import util::color::{Color, rgb};
import util::color::css_colors::{white, black};
import base::{LayoutData, NTree};
import layout::base::{LayoutData, NTree};
type SpecifiedStyle = {mut background_color : Option<Color>,
mut display_type : Option<DisplayType>,

View file

@ -13,7 +13,7 @@ import dvec::DVec;
import ptr::null;
import bindings;
import std::arc::ARC;
import style::Stylesheet;
import css::values::Stylesheet;
import comm::{Port, Chan};
import content::content_task::{ControlMsg, Timer};

View file

@ -1,9 +1,10 @@
#[doc="Fundamental layout structures and algorithms."]
import css::values::Unit;
import css::styles::SpecifiedStyle;
import dom::base::{Element, ElementKind, HTMLDivElement, HTMLImageElement, Node, NodeData};
import dom::base::{NodeKind};
import dom::rcu;
import dom::style::Unit;
import gfx::geometry;
import gfx::geometry::{au, zero_size_au};
import geom::point::Point2D;
@ -14,7 +15,6 @@ import util::tree;
import util::color::Color;
import text::TextBox;
import traverse::extended_full_traversal;
import style::style::{SpecifiedStyle};
import vec::{push, push_all};
import std::net::url::Url;
import resource::image_cache_task;

View file

@ -1,6 +1,6 @@
#[doc="Block layout."]
import dom::style::{Px, Mm, Pt, Auto, Percent, Unit};
import css::values::{Px, Mm, Pt, Auto, Percent, Unit};
import geom::point::Point2D;
import geom::size::Size2D;
import gfx::geometry::{px_to_au, au};

View file

@ -1,7 +1,7 @@
#[doc="Creates CSS boxes from a DOM."]
import css::values::{DisplayType, DisBlock, DisInline, DisNone};
import dom::base::{ElementData, HTMLDivElement, HTMLImageElement, Element, Text, Node};
import dom::style::{DisplayType, DisBlock, DisInline, DisNone};
import gfx::geometry::zero_size_au;
import layout::base::{Appearance, BTree, BlockBox, Box, BoxKind, InlineBox, IntrinsicBox, NTree};
import layout::base::{TextBoxKind};

View file

@ -1,8 +1,8 @@
#[doc="Inline layout."]
import base::{Box, InlineBox, BTree};
import css::values::{Auto, Px};
import dom::rcu;
import dom::style::{Auto, Px};
import geom::point::Point2D;
import geom::size::Size2D;
import gfx::geometry::{au, px_to_au};

View file

@ -6,13 +6,13 @@
import std::arc::ARC;
import display_list_builder::build_display_list;
import dom::base::Node;
import dom::style::Stylesheet;
import css::values::Stylesheet;
import gfx::geometry::px_to_au;
import gfx::render_task;
import render_task::RenderTask;
import resource::image_cache_task::ImageCacheTask;
import std::net::url::Url;
import style::apply::apply_style;
import css::resolve::apply::apply_style;
import dom::event::{Event, ReflowEvent};
import content::content_task;

View file

@ -3,13 +3,12 @@
// TODO: fail according to the css spec instead of failing when things
// are not as expected
import dom::style;
import style::{DisInline, DisBlock, DisNone, Display, TextColor, BackgroundColor, FontSize,
Height, Width, StyleDeclaration, Selector};
import parser::css_lexer::{Token, StartDescription, EndDescription,
Descendant, Child, Sibling,
Comma, Element, Attr, Description,
Eof};
import css::values::{DisInline, DisBlock, DisNone, Display, TextColor, BackgroundColor, FontSize,
Height, Width, StyleDeclaration};
// Disambiguate parsed Selector, Rule values from tokens
import css = css::values;
import tok = parser::css_lexer;
import parser::css_lexer::Token;
import comm::recv;
import option::{map, is_none};
import vec::push;
@ -39,18 +38,18 @@ impl TokenReader : TokenReaderMethods {
}
trait ParserMethods {
fn parse_element() -> Option<~style::Selector>;
fn parse_selector() -> Option<~[~Selector]>;
fn parse_element() -> Option<~css::Selector>;
fn parse_selector() -> Option<~[~css::Selector]>;
fn parse_description() -> Option<~[StyleDeclaration]>;
fn parse_rule() -> Option<~style::Rule>;
fn parse_rule() -> Option<~css::Rule>;
}
impl TokenReader : ParserMethods {
fn parse_element() -> Option<~style::Selector> {
fn parse_element() -> Option<~css::Selector> {
// Get the current element type
let elmt_name = match self.get() {
Element(tag) => { copy tag }
Eof => { return None; }
tok::Element(tag) => { copy tag }
tok::Eof => { return None; }
_ => { fail ~"Expected an element" }
};
@ -58,23 +57,23 @@ impl TokenReader : ParserMethods {
// Get the attributes associated with that element
loop {
let tok = self.get();
match tok {
Attr(attr) => { push(attr_list, copy attr); }
StartDescription | Descendant | Child | Sibling | Comma => {
self.unget(tok);
let token = self.get();
match token {
tok::Attr(attr) => { push(attr_list, copy attr); }
tok::StartDescription | tok::Descendant | tok::Child | tok::Sibling | tok::Comma => {
self.unget(token);
break;
}
Eof => { return None; }
Element(_) => fail ~"Unexpected second element without relation to first element",
EndDescription => fail ~"Unexpected '}'",
Description(_, _) => fail ~"Unexpected description"
tok::Eof => { return None; }
tok::Element(_) => fail ~"Unexpected second element without relation to first element",
tok::EndDescription => fail ~"Unexpected '}'",
tok::Description(_, _) => fail ~"Unexpected description"
}
}
return Some(~style::Element(elmt_name, attr_list));
return Some(~css::Element(elmt_name, attr_list));
}
fn parse_selector() -> Option<~[~Selector]> {
fn parse_selector() -> Option<~[~css::Selector]> {
let mut sel_list = ~[];
// Collect all the selectors that this rule applies to
@ -91,47 +90,47 @@ impl TokenReader : ParserMethods {
let built_sel <- cur_sel;
match tok {
Descendant => {
tok::Descendant => {
match self.parse_element() {
Some(elmt) => {
let new_sel = copy elmt;
cur_sel <- ~style::Descendant(built_sel, new_sel)
cur_sel <- ~css::Descendant(built_sel, new_sel)
}
None => { return None; }
}
}
Child => {
tok::Child => {
match self.parse_element() {
Some(elmt) => {
let new_sel = copy elmt;
cur_sel <- ~style::Child(built_sel, new_sel)
cur_sel <- ~css::Child(built_sel, new_sel)
}
None => { return None; }
}
}
Sibling => {
tok::Sibling => {
match self.parse_element() {
Some(elmt) => {
let new_sel = copy elmt;
cur_sel <- ~style::Sibling(built_sel, new_sel)
cur_sel <- ~css::Sibling(built_sel, new_sel)
}
None => { return None; }
}
}
StartDescription => {
tok::StartDescription => {
push(sel_list, built_sel);
self.unget(StartDescription);
self.unget(tok::StartDescription);
break;
}
Comma => {
tok::Comma => {
push(sel_list, built_sel);
self.unget(Comma);
self.unget(tok::Comma);
break;
}
Attr(_) | EndDescription | Element(_) | Description(_, _) => {
tok::Attr(_) | tok::EndDescription | tok::Element(_) | tok::Description(_, _) => {
fail #fmt["Unexpected token %? in elements", tok];
}
Eof => { return None; }
tok::Eof => { return None; }
}
}
@ -139,8 +138,8 @@ impl TokenReader : ParserMethods {
// TODO: fix this when rust gets labelled loops
let tok = self.get();
match tok {
StartDescription => { break; }
Comma => { }
tok::StartDescription => { break; }
tok::Comma => { }
_ => { self.unget(tok); }
}
}
@ -155,8 +154,8 @@ impl TokenReader : ParserMethods {
loop {
let tok = self.get();
match tok {
EndDescription => { break; }
Description(prop, val) => {
tok::EndDescription => { break; }
tok::Description(prop, val) => {
let desc = match prop {
// TODO: have color parsing return an option instead of a real value
~"background-color" => parse_color(val).map(|res| BackgroundColor(res)),
@ -169,8 +168,9 @@ impl TokenReader : ParserMethods {
};
desc.map(|res| push(desc_list, res));
}
Eof => { return None; }
StartDescription | Descendant | Child | Sibling | Comma | Element(_) | Attr(_) => {
tok::Eof => { return None; }
tok::StartDescription | tok::Descendant | tok::Child | tok::Sibling
| tok::Comma | tok::Element(_) | tok::Attr(_) => {
fail #fmt["Unexpected token %? in description", tok];
}
}
@ -179,7 +179,7 @@ impl TokenReader : ParserMethods {
return Some(desc_list);
}
fn parse_rule() -> Option<~style::Rule> {
fn parse_rule() -> Option<~css::Rule> {
// TODO: get rid of copies once match move works
let sel_list = match self.parse_selector() {
Some(list) => { copy list }
@ -200,7 +200,7 @@ impl TokenReader : ParserMethods {
}
}
fn build_stylesheet(+stream : pipes::Port<Token>) -> ~[~style::Rule] {
fn build_stylesheet(+stream : pipes::Port<Token>) -> ~[~css::Rule] {
let mut rule_list = ~[];
let reader = {stream : stream, mut lookahead : None};

View file

@ -1,6 +1,5 @@
#[doc = "Code to lex and tokenize css files."]
import dom::style;
import option::is_none;
import str::from_bytes;
import vec::push;
@ -32,7 +31,7 @@ enum Token {
Sibling,
Comma,
Element(~str),
Attr(style::Attr),
Attr(css::values::Attr),
Description(~str, ~str),
Eof
}
@ -120,8 +119,8 @@ impl CssLexer : CssLexerMethods {
}
match ch {
'.' as u8 => return Attr(style::Includes(~"class", self.input_state.parse_ident())),
'#' as u8 => return Attr(style::Includes(~"id", self.input_state.parse_ident())),
'.' as u8 => return Attr(css::values::Includes(~"class", self.input_state.parse_ident())),
'#' as u8 => return Attr(css::values::Includes(~"id", self.input_state.parse_ident())),
'[' as u8 => {
let attr_name = self.input_state.parse_ident();
@ -131,21 +130,21 @@ impl CssLexer : CssLexerMethods {
}
if ch == ']' as u8 {
return Attr(style::Exists(attr_name));
return Attr(css::values::Exists(attr_name));
} else if ch == '=' as u8 {
let attr_val = self.input_state.parse_ident();
self.input_state.expect(']' as u8);
return Attr(style::Exact(attr_name, attr_val));
return Attr(css::values::Exact(attr_name, attr_val));
} else if ch == '~' as u8 {
self.input_state.expect('=' as u8);
let attr_val = self.input_state.parse_ident();
self.input_state.expect(']' as u8);
return Attr(style::Includes(attr_name, attr_val));
return Attr(css::values::Includes(attr_name, attr_val));
} else if ch == '|' as u8 {
self.input_state.expect('=' as u8);
let attr_val = self.input_state.parse_ident();
self.input_state.expect(']' as u8);
return Attr(style::StartsWith(attr_name, attr_val));
return Attr(css::values::StartsWith(attr_name, attr_val));
}
fail #fmt("Unexpected symbol %c in attribute", ch as char);

View file

@ -8,7 +8,7 @@ import gfx::geometry;
import gfx::geometry::au;
import parser = parser::html_lexer;
import parser::Token;
import dom::style::Stylesheet;
import css::values::Stylesheet;
import vec::{push, push_all_move, flat_map};
import std::net::url::Url;
import resource::resource_task::{ResourceTask, Load, Payload, Done};

View file

@ -1,5 +1,4 @@
import comm::{Port, Chan};
import dom::style;
import option::is_none;
import str::from_bytes;
import vec::push;

View file

@ -1,7 +1,7 @@
use dom::base::{Attr, Comment, Doctype, DoctypeData, Element, ElementData, ElementKind};
use dom::base::{HTMLDivElement, HTMLHeadElement, HTMLImageElement, HTMLScriptElement};
use dom::base::{Node, NodeScope, Text, UnknownElement};
use dom::style::Stylesheet;
use css::values::Stylesheet;
use geom::size::Size2D;
use gfx::geometry::px_to_au;
use parser::html_builder::CSSMessage;

View file

@ -1,6 +1,6 @@
#[doc = "Helper functions to parse values of specific attributes."]
import dom::style::*;
import css::values::*;
import str::{pop_char, from_chars};
import float::from_str;
import option::map;

View file

@ -24,7 +24,6 @@ mod dom {
mod base;
mod event;
mod rcu;
mod style;
mod bindings {
mod document;
mod element;
@ -39,13 +38,16 @@ mod content {
mod content_task;
}
mod layout {
mod style {
mod css {
mod values;
mod styles;
mod resolve {
mod apply;
mod style;
mod matching;
}
}
mod layout {
mod base;
mod block;
mod box_builder;