Move create_box_data to be a method of LayoutTreeBuilder; add an explicit UA stylesheet simulation method

This commit is contained in:
Brian J. Burg 2012-09-20 10:47:32 -07:00
parent 4ec6c3f78e
commit 754bbeae41

View file

@ -1,10 +1,10 @@
/** Creates CSS boxes from a DOM. */ /** Creates CSS boxes from a DOM. */
use au = gfx::geometry; use au = gfx::geometry;
use core::dvec::DVec; use core::dvec::DVec;
use css::styles::SpecifiedStyle;
use css::values::{CSSDisplay, DisplayBlock, DisplayInline, DisplayInlineBlock, DisplayNone}; use css::values::{CSSDisplay, DisplayBlock, DisplayInline, DisplayInlineBlock, DisplayNone};
use css::values::{Inherit, Initial, Specified}; use css::values::{Inherit, Initial, Specified};
use dom::base::{ElementData, HTMLDivElement, HTMLImageElement}; use dom::base::*;
use dom::base::{Element, Text, Node, Doctype, Comment, NodeTree};
use layout::base::{RenderBox, BoxData, GenericBox, ImageBox, TextBox, RenderBoxTree}; use layout::base::{RenderBox, BoxData, GenericBox, ImageBox, TextBox, RenderBoxTree};
use layout::base::{FlowContext, FlowContextData, BlockFlow, InlineFlow, InlineBlockFlow, RootFlow, FlowTree}; use layout::base::{FlowContext, FlowContextData, BlockFlow, InlineFlow, InlineBlockFlow, RootFlow, FlowTree};
use layout::block::BlockFlowData; use layout::block::BlockFlowData;
@ -49,19 +49,15 @@ impl LayoutTreeBuilder {
let n_str = fmt!("%?", cur_node.read(|n| copy n.kind )); let n_str = fmt!("%?", cur_node.read(|n| copy n.kind ));
debug!("Considering node: %?", n_str); debug!("Considering node: %?", n_str);
// TODO: remove this once UA styles work
// TODO: handle interactions with 'float', 'position' (CSS 2.1, Section 9.7) // TODO: handle interactions with 'float', 'position' (CSS 2.1, Section 9.7)
let display = match style.display_type { let simulated_display = match self.simulate_UA_display_rules(cur_node, style) {
Specified(v) => match v { DisplayNone => return, // tree ends here if 'display: none'
// tree ends here if 'display: none' v => v
DisplayNone => return,
_ => v
},
Inherit | Initial => DisplayInline // TODO: fail instead once resolve works
//fail ~"Node should have resolved value for 'display', but was initial or inherit"
}; };
// first, create the proper box kind, based on node characteristics // first, create the proper box kind, based on node characteristics
let box_data = match cur_node.create_box_data(layout_ctx, display) { let box_data = match self.create_box_data(layout_ctx, cur_node, simulated_display) {
None => return, None => return,
Some(data) => data Some(data) => data
}; };
@ -78,7 +74,7 @@ impl LayoutTreeBuilder {
} }
}, },
ImageBox(*) | GenericBox => { ImageBox(*) | GenericBox => {
match display { match simulated_display {
DisplayInline | DisplayInlineBlock => { DisplayInline | DisplayInlineBlock => {
/* if inline, try to put into inline context, /* if inline, try to put into inline context,
making a new one if necessary */ making a new one if necessary */
@ -92,7 +88,7 @@ impl LayoutTreeBuilder {
DisplayBlock => { DisplayBlock => {
self.make_ctx(BlockFlow(BlockFlowData()), tree::empty()) self.make_ctx(BlockFlow(BlockFlowData()), tree::empty())
}, },
_ => fail fmt!("unsupported display type in box generation: %?", display) _ => fail fmt!("unsupported display type in box generation: %?", simulated_display)
} }
} }
}; };
@ -144,6 +140,27 @@ impl LayoutTreeBuilder {
fail ~"TODO: handle case where an inline is split by a block" fail ~"TODO: handle case where an inline is split by a block"
} }
priv fn simulate_UA_display_rules(node: Node, style: SpecifiedStyle) -> CSSDisplay {
let resolved = match style.display_type {
Inherit | Initial => DisplayInline, // TODO: remove once resolve works
Specified(v) => v
};
if (resolved == DisplayNone) { return resolved; }
do node.read |n| {
match n.kind {
~Doctype(*) | ~Comment(*) => DisplayNone,
~Text(*) => DisplayInline,
~Element(e) => match e.kind {
~HTMLHeadElement(*) => DisplayNone,
~HTMLScriptElement(*) => DisplayNone,
_ => resolved
}
}
}
}
/** entry point for box creation. Should only be /** entry point for box creation. Should only be
called on root DOM element. */ called on root DOM element. */
fn construct_trees(layout_ctx: &LayoutContext, root: Node) -> Result<@RenderBox, ()> { fn construct_trees(layout_ctx: &LayoutContext, root: Node) -> Result<@RenderBox, ()> {
@ -165,16 +182,12 @@ impl LayoutTreeBuilder {
debug!("Created box: %s", ret.debug_str()); debug!("Created box: %s", ret.debug_str());
ret ret
} }
}
trait PrivateBuilderMethods { /* Based on the DOM node type, create a specific type of box */
fn create_box_data(layout_ctx: &LayoutContext, display: CSSDisplay) -> Option<BoxData>; fn create_box_data(layout_ctx: &LayoutContext, node: Node, display: CSSDisplay) -> Option<BoxData> {
} // TODO: handle more types of nodes.
do node.read |n| {
impl Node : PrivateBuilderMethods { match n.kind {
fn create_box_data(layout_ctx: &LayoutContext, display: CSSDisplay) -> Option<BoxData> {
do self.read |node| {
match node.kind {
~Doctype(*) | ~Comment(*) => None, ~Doctype(*) | ~Comment(*) => None,
~Text(string) => { ~Text(string) => {
// TODO: clean this up. Fonts should not be created here. // TODO: clean this up. Fonts should not be created here.