Factor out elements into a generic type

This commit is contained in:
Patrick Walton 2012-05-24 12:01:37 -07:00
parent 7f3d010fd4
commit c26ed2aa90
5 changed files with 66 additions and 36 deletions

View file

@ -5,15 +5,29 @@ import util::tree;
enum node_data = { enum node_data = {
tree: tree::fields<node>, tree: tree::fields<node>,
kind: node_kind, kind: ~node_kind,
}; };
enum node_kind { enum node_kind {
nk_div, nk_element(element),
nk_img(size<au>),
nk_text(str) nk_text(str)
} }
class element {
let tag_name: str;
let subclass: ~element_subclass;
new(tag_name: str, -subclass: ~element_subclass) {
self.tag_name = tag_name;
self.subclass = subclass;
}
}
enum element_subclass {
es_div,
es_img(size<au>)
}
#[doc="The rd_aux data is a (weak) pointer to the layout data, which contains #[doc="The rd_aux data is a (weak) pointer to the layout data, which contains
the CSS info as well as the primary box. Note that there may be multiple the CSS info as well as the primary box. Note that there may be multiple
boxes per DOM node."] boxes per DOM node."]
@ -24,9 +38,9 @@ type node_scope = rcu::scope<node_data, layout_data>;
fn node_scope() -> node_scope { rcu::scope() } fn node_scope() -> node_scope { rcu::scope() }
impl methods for node_scope { impl methods for node_scope {
fn new_node(+k: node_kind) -> node { fn new_node(-k: node_kind) -> node {
self.handle(node_data({tree: tree::empty(), self.handle(node_data({tree: tree::empty(),
kind: k})) kind: ~k}))
} }
} }

View file

@ -1,6 +1,6 @@
#[doc="Fundamental layout structures and algorithms."] #[doc="Fundamental layout structures and algorithms."]
import dom::base::{nk_div, nk_img, node_data, node_kind, node}; import dom::base::{element, es_div, es_img, node_data, node_kind, node};
import dom::rcu; import dom::rcu;
import dom::rcu::reader_methods; import dom::rcu::reader_methods;
import gfx::geom; import gfx::geom;

View file

@ -1,6 +1,6 @@
#[doc="Creates CSS boxes from a DOM."] #[doc="Creates CSS boxes from a DOM."]
import dom::base::{nk_div, nk_img, nk_text, node}; import dom::base::{element, es_div, es_img, nk_element, nk_text, node};
import dom::rcu::reader_methods; import dom::rcu::reader_methods;
import gfx::geom; import gfx::geom;
import /*layout::*/base::{bk_block, bk_inline, bk_intrinsic, bk_text, box}; import /*layout::*/base::{bk_block, bk_inline, bk_intrinsic, bk_text, box};
@ -119,9 +119,13 @@ impl box_builder_priv for node {
"] "]
fn determine_box_kind() -> box_kind { fn determine_box_kind() -> box_kind {
alt self.rd({ |n| n.kind }) { alt self.rd({ |n| n.kind }) {
nk_img(size) { bk_intrinsic(@size) } ~nk_text(string) { bk_text(@text_box(string)) }
nk_div { bk_block } ~nk_element(element) {
nk_text(s) { bk_text(@text_box(s)) } alt *element.subclass {
es_div { bk_block }
es_img(size) { bk_intrinsic(@size) }
}
}
} }
} }
} }

View file

@ -1,6 +1,7 @@
#[doc="High-level interface to CSS selector matching."] #[doc="High-level interface to CSS selector matching."]
import dom::base::{nk_div, nk_img, nk_text, node, node_kind}; import dom::base::{element, es_div, es_img, nk_element, nk_text, node};
import dom::base::node_kind;
import dom::rcu::reader_methods; import dom::rcu::reader_methods;
import /*layout::*/base::*; // FIXME: resolve bug requires * import /*layout::*/base::*; // FIXME: resolve bug requires *
@ -14,12 +15,17 @@ enum display {
} }
#[doc="Returns the default style for the given node kind."] #[doc="Returns the default style for the given node kind."]
fn default_style_for_node_kind(kind : node_kind) -> computed_style { fn default_style_for_node_kind(kind: node_kind) -> computed_style {
alt kind { alt kind {
nk_div { computed_style({ mut display: di_block }) } nk_text(*) {
nk_img(*) | nk_text(*) {
computed_style({ mut display: di_inline }) computed_style({ mut display: di_inline })
} }
nk_element(element) {
alt *element.subclass {
es_div { computed_style({ mut display: di_block }) }
es_img(*) { computed_style({ mut display: di_inline }) }
}
}
} }
} }
@ -33,7 +39,7 @@ impl style_priv for node {
"] "]
fn recompute_style() { fn recompute_style() {
let default_style: computed_style = let default_style: computed_style =
default_style_for_node_kind(self.rd { |n| n.kind }); default_style_for_node_kind(self.rd { |n| *n.kind });
#debug("recomputing style; parent node:"); #debug("recomputing style; parent node:");
self.dump(); self.dump();

View file

@ -1,7 +1,8 @@
#[doc="Constructs a DOM tree from an incoming token stream."] #[doc="Constructs a DOM tree from an incoming token stream."]
import dom::rcu::writer_methods; import dom::rcu::writer_methods;
import dom::base::{methods, rd_tree_ops, wr_tree_ops}; import dom::base::{element, es_div, es_img, methods, nk_element, nk_text};
import dom::base::{rd_tree_ops, wr_tree_ops};
import dom = dom::base; import dom = dom::base;
import parser = parser::html; import parser = parser::html;
import html::token; import html::token;
@ -11,24 +12,28 @@ fn link_up_attribute(scope: dom::node_scope, node: dom::node, key: str,
value: str) { value: str) {
// TODO: Implement atoms so that we don't always perform string // TODO: Implement atoms so that we don't always perform string
// comparisons. // comparisons.
// FIXME: This is wrong... we should not have DIV and IMG be separate types
// of nodes and instead have them inherit from Element, obviously.
scope.rd(node) { scope.rd(node) {
|node_contents| |node_contents|
alt node_contents.kind { alt *node_contents.kind {
dom::nk_img(dims) if key == "width" { dom::nk_element(element) {
alt int::from_str(value) { alt *element.subclass {
none { /* drop on the floor */ } es_img(dimensions) if key == "width" {
some(s) { dims.width = geom::px_to_au(s); } alt int::from_str(value) {
none { /* drop on the floor */ }
some(s) { dimensions.width = geom::px_to_au(s); }
}
}
es_img(dimensions) if key == "height" {
alt int::from_str(value) {
none { /* drop on the floor */ }
some(s) { dimensions.height = geom::px_to_au(s); }
}
}
es_div | es_img(*) {
// Drop on the floor.
}
} }
} }
dom::nk_img(dims) if key == "height" {
alt int::from_str(value) {
none { /* drop on the floor */ }
some(s) { dims.height = geom::px_to_au(s); }
}
}
dom::nk_div | dom::nk_img(*) { /* drop on the floor */ }
dom::nk_text(*) { dom::nk_text(*) {
fail "attempt to link up an attribute to a text node" fail "attempt to link up an attribute to a text node"
} }
@ -39,7 +44,7 @@ fn link_up_attribute(scope: dom::node_scope, node: dom::node, key: str,
fn build_dom(scope: dom::node_scope, fn build_dom(scope: dom::node_scope,
stream: port<token>) -> dom::node { stream: port<token>) -> dom::node {
// The current reference node. // The current reference node.
let mut cur = scope.new_node(dom::nk_div); let mut cur = scope.new_node(dom::nk_element(element("html", ~es_div)));
loop { loop {
let token = stream.recv(); let token = stream.recv();
#debug["token=%?", token]; #debug["token=%?", token];
@ -47,16 +52,17 @@ fn build_dom(scope: dom::node_scope,
parser::to_eof { break; } parser::to_eof { break; }
parser::to_start_opening_tag("div") { parser::to_start_opening_tag("div") {
#debug["DIV"]; #debug["DIV"];
let new_node = scope.new_node( let new_node =
dom::nk_div); scope.new_node(dom::nk_element(element("div", ~es_div)));
scope.add_child(cur, new_node); scope.add_child(cur, new_node);
cur = new_node; cur = new_node;
} }
parser::to_start_opening_tag("img") { parser::to_start_opening_tag("img") {
#debug["IMG"]; #debug["IMG"];
let new_node = scope.new_node( let new_node =
dom::nk_img({mut width: geom::px_to_au(100), scope.new_node(dom::nk_element(element("img",
mut height: geom::px_to_au(100)})); ~es_img({mut width: geom::px_to_au(100),
mut height: geom::px_to_au(100)}))));
scope.add_child(cur, new_node); scope.add_child(cur, new_node);
cur = new_node; cur = new_node;
} }