aboutsummaryrefslogtreecommitdiffstats
path: root/src/servo/parser/html_builder.rs
diff options
context:
space:
mode:
authorBrian J. Burg <burg@cs.washington.edu>2012-09-06 15:44:12 -0700
committerBrian J. Burg <burg@cs.washington.edu>2012-09-06 15:44:12 -0700
commit977389d2a394c4219d769815718ff577e3e9d4e3 (patch)
treec589971cfa1423ef654b3ac4da08690a949ee867 /src/servo/parser/html_builder.rs
parent10f1729a71f0a8cc0801e8cc6eeedfa8e9117f0f (diff)
downloadservo-977389d2a394c4219d769815718ff577e3e9d4e3.tar.gz
servo-977389d2a394c4219d769815718ff577e3e9d4e3.zip
Move parsers and lexers to css/ and html/ top-level dirs; fix some s/import/use/
Diffstat (limited to 'src/servo/parser/html_builder.rs')
-rw-r--r--src/servo/parser/html_builder.rs273
1 files changed, 0 insertions, 273 deletions
diff --git a/src/servo/parser/html_builder.rs b/src/servo/parser/html_builder.rs
deleted file mode 100644
index 57b1cc6d466..00000000000
--- a/src/servo/parser/html_builder.rs
+++ /dev/null
@@ -1,273 +0,0 @@
-#[doc="Constructs a DOM tree from an incoming token stream."]
-
-import dom::base::{Attr, Element, ElementData, ElementKind, HTMLDivElement, HTMLHeadElement,
- HTMLScriptElement};
-import dom::base::{HTMLImageElement, Node, NodeScope, Text, UnknownElement};
-import geom::size::Size2D;
-import gfx::geometry;
-import gfx::geometry::au;
-import parser = parser::html_lexer;
-import parser::Token;
-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};
-import to_str::ToStr;
-
-enum CSSMessage {
- File(Url),
- Exit
-}
-
-enum js_message {
- js_file(Url),
- js_exit
-}
-
-#[allow(non_implicitly_copyable_typarams)]
-fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) {
- // TODO: Implement atoms so that we don't always perform string comparisons.
- scope.read(node, |node_contents| {
- match *node_contents.kind {
- Element(element) => {
- element.attrs.push(~Attr(copy key, copy value));
- match *element.kind {
- HTMLImageElement(img) if key == ~"width" => {
- match int::from_str(value) {
- None => {
- // Drop on the floor.
- }
- Some(s) => { img.size.width = geometry::px_to_au(s); }
- }
- }
- HTMLImageElement(img) if key == ~"height" => {
- match int::from_str(value) {
- None => {
- // Drop on the floor.
- }
- Some(s) => {
- img.size.height = geometry::px_to_au(s);
- }
- }
- }
- HTMLDivElement | HTMLImageElement(*) | HTMLHeadElement |
- HTMLScriptElement | UnknownElement => {
- // Drop on the floor.
- }
- }
- }
-
- _ => {
- fail ~"attempt to link up an attribute to an unstyleable node"
- }
- }
- })
-}
-
-fn build_element_kind(tag_name: ~str) -> ~ElementKind {
- match tag_name {
- ~"div" => ~HTMLDivElement,
- ~"img" => {
- ~HTMLImageElement({ mut size: Size2D(geometry::px_to_au(100),
- geometry::px_to_au(100))
- })
- }
- ~"script" => ~HTMLScriptElement,
- ~"head" => ~HTMLHeadElement,
- _ => ~UnknownElement
- }
-}
-
-#[doc="Runs a task that coordinates parsing links to css stylesheets.
-
-This function should be spawned in a separate task and spins waiting
-for the html builder to find links to css stylesheets and sends off
-tasks to parse each link. When the html process finishes, it notifies
-the listener, who then collects the css rules from each task it
-spawned, collates them, and sends them to the given result channel.
-
-# Arguments
-
-* `to_parent` - A channel on which to send back the full set of rules.
-* `from_parent` - A port on which to receive new links.
-
-"]
-fn css_link_listener(to_parent : comm::Chan<Stylesheet>, from_parent : comm::Port<CSSMessage>,
- resource_task: ResourceTask) {
- let mut result_vec = ~[];
-
- loop {
- match from_parent.recv() {
- File(url) => {
- let result_port = comm::Port();
- let result_chan = comm::Chan(result_port);
- // TODO: change copy to move once we have match move
- let url = copy url;
- task::spawn(|| {
- // TODO: change copy to move once we can move into closures
- let css_stream = css_lexer::spawn_css_lexer_task(copy url, resource_task);
- let mut css_rules = css_builder::build_stylesheet(css_stream);
- result_chan.send(css_rules);
- });
-
- push(result_vec, result_port);
- }
- Exit => {
- break;
- }
- }
- }
-
- let css_rules = flat_map(result_vec, |result_port| { result_port.recv() });
-
- to_parent.send(css_rules);
-}
-
-fn js_script_listener(to_parent : comm::Chan<~[~[u8]]>, from_parent : comm::Port<js_message>,
- resource_task: ResourceTask) {
- let mut result_vec = ~[];
-
- loop {
- match from_parent.recv() {
- js_file(url) => {
- let result_port = comm::Port();
- let result_chan = comm::Chan(result_port);
- // TODO: change copy to move once we have match move
- let url = copy url;
- do task::spawn || {
- let input_port = Port();
- // TODO: change copy to move once we can move into closures
- resource_task.send(Load(copy url, input_port.chan()));
-
- let mut buf = ~[];
- loop {
- match input_port.recv() {
- Payload(data) => {
- buf += data;
- }
- Done(Ok(*)) => {
- result_chan.send(buf);
- break;
- }
- Done(Err(*)) => {
- #error("error loading script %s", url.to_str());
- }
- }
- }
- }
- push(result_vec, result_port);
- }
- js_exit => {
- break;
- }
- }
- }
-
- let js_scripts = vec::map(result_vec, |result_port| result_port.recv());
- to_parent.send(js_scripts);
-}
-
-#[allow(non_implicitly_copyable_typarams)]
-fn build_dom(scope: NodeScope, stream: comm::Port<Token>, url: Url,
- resource_task: ResourceTask) -> (Node, comm::Port<Stylesheet>, comm::Port<~[~[u8]]>) {
- // The current reference node.
- let mut cur_node = scope.new_node(Element(ElementData(~"html", ~HTMLDivElement)));
- // We will spawn a separate task to parse any css that is
- // encountered, each link to a stylesheet is sent to the waiting
- // task. After the html sheet has been fully read, the spawned
- // task will collect the results of all linked style data and send
- // it along the returned port.
- let style_port = comm::Port();
- let child_chan = comm::Chan(style_port);
- let style_chan = task::spawn_listener(|child_port| {
- css_link_listener(child_chan, child_port, resource_task);
- });
-
- let js_port = comm::Port();
- let child_chan = comm::Chan(js_port);
- let js_chan = task::spawn_listener(|child_port| {
- js_script_listener(child_chan, child_port, resource_task);
- });
-
- loop {
- let token = stream.recv();
- match token {
- parser::Eof => { break; }
- parser::StartOpeningTag(tag_name) => {
- #debug["starting tag %s", tag_name];
- let element_kind = build_element_kind(tag_name);
- let new_node = scope.new_node(Element(ElementData(copy tag_name, element_kind)));
- scope.add_child(cur_node, new_node);
- cur_node = new_node;
- }
- parser::Attr(key, value) => {
- #debug["attr: %? = %?", key, value];
- link_up_attribute(scope, cur_node, copy key, copy value);
- }
- parser::EndOpeningTag => {
- #debug("end opening tag");
- }
- // TODO: Fail more gracefully (i.e. according to the HTML5
- // spec) if we close more tags than we open.
- parser::SelfCloseTag => {
- //TODO: check for things other than the link tag
- scope.read(cur_node, |n| {
- match *n.kind {
- Element(elmt) if elmt.tag_name == ~"link" => {
- match elmt.get_attr(~"rel") {
- Some(r) if r == ~"stylesheet" => {
- match elmt.get_attr(~"href") {
- Some(filename) => {
- #debug["Linking to a css sheet named: %s", filename];
- // FIXME: Need to base the new url on the current url
- let new_url = make_url(filename, Some(copy url));
- style_chan.send(File(new_url));
- }
- None => { /* fall through*/ }
- }
- }
- _ => { /* fall through*/ }
- }
- }
- _ => { /* fall through*/ }
- }
- });
- cur_node = scope.get_parent(cur_node).get();
- }
- parser::EndTag(*) => {
- // TODO: Assert that the closing tag has the right name.
- scope.read(cur_node, |n| {
- match *n.kind {
- Element(elmt) if elmt.tag_name == ~"script" => {
- match elmt.get_attr(~"src") {
- Some(filename) => {
- #debug["Linking to a js script named: %s", filename];
- let new_url = make_url(filename, Some(copy url));
- js_chan.send(js_file(new_url));
- }
- None => { /* fall through */ }
- }
- }
- _ => { /* fall though */ }
- }
- });
- cur_node = scope.get_parent(cur_node).get();
- }
- parser::Text(s) if !s.is_whitespace() => {
- let new_node = scope.new_node(Text(copy s));
- scope.add_child(cur_node, new_node);
- }
- parser::Text(_) => {
- // FIXME: Whitespace should not be ignored.
- }
- parser::Doctype => {
- // TODO: Do something here...
- }
- }
- }
-
- style_chan.send(Exit);
- js_chan.send(js_exit);
-
- return (cur_node, style_port, js_port);
-}