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 = {
tree: tree::fields<node>,
kind: node_kind,
kind: ~node_kind,
};
enum node_kind {
nk_div,
nk_img(size<au>),
nk_element(element),
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
the CSS info as well as the primary box. Note that there may be multiple
boxes per DOM node."]
@ -24,9 +38,9 @@ type node_scope = rcu::scope<node_data, layout_data>;
fn node_scope() -> node_scope { rcu::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(),
kind: k}))
kind: ~k}))
}
}

View file

@ -1,6 +1,6 @@
#[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::reader_methods;
import gfx::geom;

View file

@ -1,6 +1,6 @@
#[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 gfx::geom;
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 {
alt self.rd({ |n| n.kind }) {
nk_img(size) { bk_intrinsic(@size) }
nk_div { bk_block }
nk_text(s) { bk_text(@text_box(s)) }
~nk_text(string) { bk_text(@text_box(string)) }
~nk_element(element) {
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."]
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 /*layout::*/base::*; // FIXME: resolve bug requires *
@ -14,12 +15,17 @@ enum display {
}
#[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 {
nk_div { computed_style({ mut display: di_block }) }
nk_img(*) | nk_text(*) {
nk_text(*) {
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() {
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:");
self.dump();

View file

@ -1,7 +1,8 @@
#[doc="Constructs a DOM tree from an incoming token stream."]
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 parser = parser::html;
import html::token;
@ -11,24 +12,28 @@ fn link_up_attribute(scope: dom::node_scope, node: dom::node, key: str,
value: str) {
// TODO: Implement atoms so that we don't always perform string
// 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) {
|node_contents|
alt node_contents.kind {
dom::nk_img(dims) if key == "width" {
alt int::from_str(value) {
none { /* drop on the floor */ }
some(s) { dims.width = geom::px_to_au(s); }
alt *node_contents.kind {
dom::nk_element(element) {
alt *element.subclass {
es_img(dimensions) if key == "width" {
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(*) {
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,
stream: port<token>) -> dom::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 {
let token = stream.recv();
#debug["token=%?", token];
@ -47,16 +52,17 @@ fn build_dom(scope: dom::node_scope,
parser::to_eof { break; }
parser::to_start_opening_tag("div") {
#debug["DIV"];
let new_node = scope.new_node(
dom::nk_div);
let new_node =
scope.new_node(dom::nk_element(element("div", ~es_div)));
scope.add_child(cur, new_node);
cur = new_node;
}
parser::to_start_opening_tag("img") {
#debug["IMG"];
let new_node = scope.new_node(
dom::nk_img({mut width: geom::px_to_au(100),
mut height: geom::px_to_au(100)}));
let new_node =
scope.new_node(dom::nk_element(element("img",
~es_img({mut width: geom::px_to_au(100),
mut height: geom::px_to_au(100)}))));
scope.add_child(cur, new_node);
cur = new_node;
}