Fixed the changing alt syntax and cleaned up some compiler warnings

This commit is contained in:
Margaret Meyerhofer 2012-08-03 15:16:08 -07:00
parent f290f18087
commit 0b796c410c
40 changed files with 482 additions and 485 deletions

@ -1 +1 @@
Subproject commit 6a72d19ff22e0d0539b8bf6cb22ac3378625cca8 Subproject commit 377d4a6eecef416c9fc082914c265c2ece765909

@ -1 +1 @@
Subproject commit 1159f92f8a66a4f9aaa9c8c91c437dc36221dfcc Subproject commit b63c020bacba761619d7da85cf112c4fae75b6d5

@ -1 +1 @@
Subproject commit a3ddb0bc112e12ec1438679378e9e0a67b86373f Subproject commit f071d5e2772973580df979a643deaf9745f5a7f7

View file

@ -9,6 +9,7 @@ export PingMsg, PongMsg;
export create_content; export create_content;
export Document; export Document;
import arc::{arc, clone};
import comm::{port, chan, listen, select2}; import comm::{port, chan, listen, select2};
import task::{spawn, spawn_listener}; import task::{spawn, spawn_listener};
import io::{read_whole_file, println}; import io::{read_whole_file, println};
@ -55,7 +56,7 @@ enum PingMsg {
} }
#[doc="Sends a ping to layout and waits for the response."] #[doc="Sends a ping to layout and waits for the response."]
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn join_layout(scope: NodeScope, layout: Layout) { fn join_layout(scope: NodeScope, layout: Layout) {
if scope.is_reader_forked() { if scope.is_reader_forked() {
@ -69,11 +70,11 @@ fn join_layout(scope: NodeScope, layout: Layout) {
class Document { class Document {
let root: Node; let root: Node;
let css_rules: Stylesheet; let css_rules: arc<Stylesheet>;
new(root: Node, +css_rules: Stylesheet) { new(root: Node, -css_rules: Stylesheet) {
self.root = root; self.root = root;
self.css_rules = css_rules; self.css_rules = arc(css_rules);
} }
} }
@ -114,24 +115,21 @@ class Content<S:Sink send copy> {
fn handle_msg(msg: either<ControlMsg,Event>) -> bool { fn handle_msg(msg: either<ControlMsg,Event>) -> bool {
alt msg { alt msg {
left(control_msg) { left(control_msg) => self.handle_control_msg(control_msg),
return self.handle_control_msg(control_msg); right(event) => self.handle_event(event)
}
right(event) {
return self.handle_event(event);
}
} }
} }
fn handle_control_msg(control_msg: ControlMsg) -> bool { fn handle_control_msg(control_msg: ControlMsg) -> bool {
alt control_msg { alt control_msg {
ParseMsg(url) { ParseMsg(url) => {
#debug["content: Received url `%s` to parse", url_to_str(url)]; #debug["content: Received url `%s` to parse", url_to_str(url)];
// Note: we can parse the next document in parallel // Note: we can parse the next document in parallel
// with any previous documents. // with any previous documents.
let stream = spawn_html_lexer_task(copy url, self.resource_task); let stream = spawn_html_lexer_task(copy url, self.resource_task);
let (root, style_port, js_port) = build_dom(self.scope, stream, url, self.resource_task); let (root, style_port, js_port) = build_dom(self.scope, stream, url,
self.resource_task);
let css_rules = style_port.recv(); let css_rules = style_port.recv();
let js_scripts = js_port.recv(); let js_scripts = js_port.recv();
@ -160,14 +158,14 @@ class Content<S:Sink send copy> {
return true; return true;
} }
ExecuteMsg(url) { ExecuteMsg(url) => {
#debug["content: Received url `%s` to execute", url_to_str(url)]; #debug["content: Received url `%s` to execute", url_to_str(url)];
alt read_whole_file(url.path) { alt read_whole_file(url.path) {
err(msg) { err(msg) => {
println(#fmt["Error opening %s: %s", url_to_str(url), msg]); println(#fmt["Error opening %s: %s", url_to_str(url), msg]);
} }
ok(bytes) { ok(bytes) => {
let cx = self.jsrt.cx(); let cx = self.jsrt.cx();
cx.set_default_options_and_version(); cx.set_default_options_and_version();
cx.set_logging_error_reporter(); cx.set_logging_error_reporter();
@ -180,7 +178,7 @@ class Content<S:Sink send copy> {
return true; return true;
} }
ExitMsg { ExitMsg => {
self.layout.send(layout_task::ExitMsg); self.layout.send(layout_task::ExitMsg);
return false; return false;
} }
@ -196,7 +194,7 @@ class Content<S:Sink send copy> {
// Send new document and relevant styles to layout // Send new document and relevant styles to layout
// FIXME: Put CSS rules in an arc or something. // FIXME: Put CSS rules in an arc or something.
self.layout.send(BuildMsg(document.root, document.css_rules)); self.layout.send(BuildMsg(document.root, clone(&document.css_rules)));
// Indicate that reader was forked so any further // Indicate that reader was forked so any further
// changes will be isolated. // changes will be isolated.
@ -205,13 +203,13 @@ class Content<S:Sink send copy> {
fn handle_event(event: Event) -> bool { fn handle_event(event: Event) -> bool {
alt event { alt event {
ResizeEvent(new_width, new_height) { ResizeEvent(new_width, new_height) => {
#debug("content got resize event: %d, %d", new_width, new_height); #debug("content got resize event: %d, %d", new_width, new_height);
alt copy self.document { alt copy self.document {
none { none => {
// Nothing to do. // Nothing to do.
} }
some(document) { some(document) => {
self.relayout(*document); self.relayout(*document);
} }
} }

View file

@ -90,14 +90,14 @@ trait node_scope {
fn new_node(-k: NodeKind) -> Node; fn new_node(-k: NodeKind) -> Node;
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
impl NodeScope of node_scope for NodeScope { impl NodeScope of node_scope for NodeScope {
fn new_node(-k: NodeKind) -> Node { fn new_node(-k: NodeKind) -> Node {
self.handle(NodeData({tree: tree::empty(), kind: ~k})) self.handle(NodeData({tree: tree::empty(), kind: ~k}))
} }
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
impl TreeReadMethods of tree::ReadMethods<Node> for NodeScope { impl TreeReadMethods of tree::ReadMethods<Node> for NodeScope {
fn each_child(node: Node, f: fn(Node) -> bool) { fn each_child(node: Node, f: fn(Node) -> bool) {
tree::each_child(self, node, f) tree::each_child(self, node, f)
@ -112,7 +112,7 @@ impl TreeReadMethods of tree::ReadMethods<Node> for NodeScope {
} }
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
impl TreeWriteMethods of tree::WriteMethods<Node> for NodeScope { impl TreeWriteMethods of tree::WriteMethods<Node> for NodeScope {
fn add_child(node: Node, child: Node) { fn add_child(node: Node, child: Node) {
tree::add_child(self, node, child) tree::add_child(self, node, child)

View file

@ -94,11 +94,11 @@ extern fn getFirstChild(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut js
unsafe { unsafe {
(*unwrap(obj)).payload.read(|nd| { (*unwrap(obj)).payload.read(|nd| {
alt nd.tree.first_child { alt nd.tree.first_child {
some(n) { some(n) => {
let obj = create(cx, n).ptr; let obj = create(cx, n).ptr;
*rval = RUST_OBJECT_TO_JSVAL(obj); *rval = RUST_OBJECT_TO_JSVAL(obj);
} }
none { none => {
*rval = JSVAL_NULL; *rval = JSVAL_NULL;
} }
} }
@ -111,11 +111,11 @@ extern fn getNextSibling(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut j
unsafe { unsafe {
(*unwrap(obj)).payload.read(|nd| { (*unwrap(obj)).payload.read(|nd| {
alt nd.tree.next_sibling { alt nd.tree.next_sibling {
some(n) { some(n) => {
let obj = create(cx, n).ptr; let obj = create(cx, n).ptr;
*rval = RUST_OBJECT_TO_JSVAL(obj); *rval = RUST_OBJECT_TO_JSVAL(obj);
} }
none { none => {
*rval = JSVAL_NULL; *rval = JSVAL_NULL;
} }
} }
@ -128,11 +128,11 @@ extern fn getTagName(cx: *JSContext, obj: *JSObject, _id: jsid, rval: *mut jsval
unsafe { unsafe {
(*unwrap(obj)).payload.read(|nd| { (*unwrap(obj)).payload.read(|nd| {
alt nd.kind { alt nd.kind {
~Element(ed) { ~Element(ed) => {
let s = str(ed.tag_name); let s = str(copy ed.tag_name);
*rval = domstring_to_jsval(cx, s); *rval = domstring_to_jsval(cx, s);
} }
_ { _ => {
//XXXjdm should probably read the spec to figure out what to do here //XXXjdm should probably read the spec to figure out what to do here
*rval = JSVAL_NULL; *rval = JSVAL_NULL;
} }

View file

@ -55,10 +55,10 @@ fn jsval_to_str(cx: *JSContext, v: jsval) -> result<~str, ()> {
unsafe fn domstring_to_jsval(cx: *JSContext, str: DOMString) -> jsval { unsafe fn domstring_to_jsval(cx: *JSContext, str: DOMString) -> jsval {
alt str { alt str {
null_string { null_string => {
JSVAL_NULL JSVAL_NULL
} }
str(s) { str(s) => {
str::as_buf(s, |buf, len| { str::as_buf(s, |buf, len| {
let cbuf = unsafe::reinterpret_cast(buf); let cbuf = unsafe::reinterpret_cast(buf);
RUST_STRING_TO_JSVAL(JS_NewStringCopyN(cx, cbuf, len as libc::size_t)) RUST_STRING_TO_JSVAL(JS_NewStringCopyN(cx, cbuf, len as libc::size_t))

View file

@ -210,7 +210,7 @@ impl WriterMethods<T:copy send,A> for Scope<T,A> {
f(*h.write_ptr()) f(*h.write_ptr())
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn handle(v: T) -> Handle<T,A> unsafe { fn handle(v: T) -> Handle<T,A> unsafe {
let d: *HandleData<T,A> = let d: *HandleData<T,A> =
unsafe::reinterpret_cast( unsafe::reinterpret_cast(
@ -226,7 +226,7 @@ impl WriterMethods<T:copy send,A> for Scope<T,A> {
} }
#[cfg(test)] #[cfg(test)]
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
mod test { mod test {
type animal = {name: ~str, species: species}; type animal = {name: ~str, species: species};
@ -250,15 +250,15 @@ mod test {
fn mutate(a: animal) { fn mutate(a: animal) {
alt a.species { alt a.species {
chicken(c) { c.eggs_per_day += 1u; } chicken(c) => c.eggs_per_day += 1u,
bull(c) { c.horns += 1u; } bull(c) => c.horns += 1u
} }
} }
fn read_characteristic(a: animal) -> uint { fn read_characteristic(a: animal) -> uint {
alt a.species { alt a.species {
chicken(c) { c.eggs_per_day } chicken(c) => c.eggs_per_day,
bull(c) { c.horns } bull(c) => c.horns
} }
} }

View file

@ -42,7 +42,9 @@ class Engine<S:Sink send copy> {
fn handle_request(request: Msg) -> bool { fn handle_request(request: Msg) -> bool {
alt request { alt request {
LoadURLMsg(url) { LoadURLMsg(url) => {
// TODO: change copy to move once we have alt move
let url = copy url;
if url.path.ends_with(".js") { if url.path.ends_with(".js") {
self.content.send(ExecuteMsg(url)) self.content.send(ExecuteMsg(url))
} else { } else {
@ -51,7 +53,7 @@ class Engine<S:Sink send copy> {
return true; return true;
} }
ExitMsg(sender) { ExitMsg(sender) => {
self.content.send(content::ExitMsg); self.content.send(content::ExitMsg);
self.layout.send(layout_task::ExitMsg); self.layout.send(layout_task::ExitMsg);

View file

@ -59,15 +59,15 @@ fn PngSink(output: chan<~[u8]>) -> PngSink {
loop { loop {
alt po.recv() { alt po.recv() {
BeginDrawing(sender) { BeginDrawing(sender) => {
#debug("pngsink: begin_drawing"); #debug("pngsink: begin_drawing");
sender.send(draw_target); sender.send(draw_target);
} }
Draw(sender, dt) { Draw(sender, dt) => {
#debug("pngsink: draw"); #debug("pngsink: draw");
do_draw(sender, dt, output, cairo_surf); do_draw(sender, dt, output, cairo_surf);
} }
Exit { break } Exit => { break }
} }
} }

View file

@ -47,7 +47,7 @@ fn Renderer<S: Sink send copy>(sink: S) -> comm::chan<Msg> {
loop { loop {
alt po.recv() { alt po.recv() {
RenderMsg(display_list) { RenderMsg(display_list) => {
#debug("renderer: got render request"); #debug("renderer: got render request");
let draw_target = draw_target_po.recv(); let draw_target = draw_target_po.recv();
let (ch, po) = pipes::stream(); let (ch, po) = pipes::stream();
@ -64,7 +64,7 @@ fn Renderer<S: Sink send copy>(sink: S) -> comm::chan<Msg> {
sink.draw(draw_target_ch, draw_target); sink.draw(draw_target_ch, draw_target);
} }
} }
ExitMsg(response_ch) { ExitMsg(response_ch) => {
response_ch.send(()); response_ch.send(());
break; break;
} }
@ -88,18 +88,10 @@ fn draw_display_list(draw_target: AzDrawTargetRef, display_list: dl::display_lis
#debug["drawing %?", item]; #debug["drawing %?", item];
alt item.item_type { alt item.item_type {
dl::display_item_solid_color(r, g, b) { dl::display_item_solid_color(r, g, b) => draw_solid_color(draw_target, item, r, g, b),
draw_solid_color(draw_target, item, r, g, b); dl::display_item_image(image) => draw_image(draw_target, item, *image),
} dl::display_item_text(text_run) => draw_text(draw_target, item, text_run),
dl::display_item_image(image) { dl::padding(*) => fail ~"should never see padding"
draw_image(draw_target, item, *image);
}
dl::display_item_text(text_run) {
draw_text(draw_target, item, text_run);
}
dl::padding(*) {
fail ~"should never see padding";
}
} }
} }
} }
@ -141,11 +133,11 @@ fn draw_image(draw_target: AzDrawTargetRef, item: dl::display_item, image: arc<~
let color = i % 4; let color = i % 4;
let pixel = i / 4; let pixel = i / 4;
alt color { alt color {
0 { image.data[pixel * 3 + 2] } 0 => image.data[pixel * 3 + 2],
1 { image.data[pixel * 3 + 1] } 1 => image.data[pixel * 3 + 1],
2 { image.data[pixel * 3 + 0] } 2 => image.data[pixel * 3 + 0],
3 { 0xffu8 } 3 => 0xffu8,
_ { fail } _ => fail
} }
}; };

View file

@ -15,7 +15,7 @@ type image_surface = {
impl format for format { impl format for format {
fn bpp() -> uint { fn bpp() -> uint {
alt self { alt self {
fo_rgba_8888 { 32u } fo_rgba_8888 => 32u
} }
} }
} }

View file

@ -180,10 +180,10 @@ impl layout_methods for @Box {
#[doc="The main reflow routine."] #[doc="The main reflow routine."]
fn reflow(available_width: au) { fn reflow(available_width: au) {
alt self.kind { alt self.kind {
BlockBox { self.reflow_block(available_width) } BlockBox => self.reflow_block(available_width),
InlineBox { self.reflow_inline(available_width) } InlineBox => self.reflow_inline(available_width),
IntrinsicBox(size) { self.reflow_intrinsic(*size) } IntrinsicBox(size) => self.reflow_intrinsic(*size),
TextBox(subbox) { self.reflow_text(available_width, subbox) } TextBox(subbox) => self.reflow_text(available_width, subbox)
} }
} }

View file

@ -55,12 +55,10 @@ impl methods for ctxt {
// Add the child's box to the current enclosing box or the current anonymous box. // Add the child's box to the current enclosing box or the current anonymous box.
alt kid.get_specified_style().display_type { alt kid.get_specified_style().display_type {
some(DisBlock) { some(DisBlock) => BTree.add_child(self.parent_box, kid_box),
BTree.add_child(self.parent_box, kid_box); some(DisInline) => {
}
some(DisInline) {
let anon_box = alt self.anon_box { let anon_box = alt self.anon_box {
none { none => {
// //
// The anonymous box inherits the attributes of its parents for now, so // The anonymous box inherits the attributes of its parents for now, so
// that properties of intrinsic boxes are not spread to their parenting // that properties of intrinsic boxes are not spread to their parenting
@ -73,14 +71,14 @@ impl methods for ctxt {
self.anon_box = some(b); self.anon_box = some(b);
b b
} }
some(b) { b } some(b) => b
}; };
BTree.add_child(anon_box, kid_box); BTree.add_child(anon_box, kid_box);
} }
some(DisNone) { some(DisNone) => {
// Nothing to do. // Nothing to do.
} }
_ { //hack for now _ => { //hack for now
} }
} }
} }
@ -104,18 +102,18 @@ impl methods for ctxt {
// Add the child's box to the current enclosing box. // Add the child's box to the current enclosing box.
alt kid.get_specified_style().display_type { alt kid.get_specified_style().display_type {
some(DisBlock) { some(DisBlock) => {
// TODO // TODO
#warn("TODO: non-inline display found inside inline box"); #warn("TODO: non-inline display found inside inline box");
BTree.add_child(self.parent_box, kid_box); BTree.add_child(self.parent_box, kid_box);
} }
some(DisInline) { some(DisInline) => {
BTree.add_child(self.parent_box, kid_box); BTree.add_child(self.parent_box, kid_box);
} }
some(DisNone) { some(DisNone) => {
// Nothing to do. // Nothing to do.
} }
_ { //hack for now _ => { //hack for now
} }
} }
} }
@ -127,10 +125,10 @@ impl methods for ctxt {
self.parent_node.dump(); self.parent_node.dump();
alt self.parent_node.get_specified_style().display_type { alt self.parent_node.get_specified_style().display_type {
some(DisBlock) { self.construct_boxes_for_block_children(); } some(DisBlock) => self.construct_boxes_for_block_children(),
some(DisInline) { self.construct_boxes_for_inline_children(); } some(DisInline) => self.construct_boxes_for_inline_children(),
some(DisNone) { /* Nothing to do. */ } some(DisNone) => { /* Nothing to do. */ }
_ { //hack for now _ => { //hack for now
} }
} }
@ -144,8 +142,8 @@ impl methods for ctxt {
"] "]
fn finish_anonymous_box_if_necessary() { fn finish_anonymous_box_if_necessary() {
alt copy self.anon_box { alt copy self.anon_box {
none { /* Nothing to do. */ } none => { /* Nothing to do. */ }
some(b) { BTree.add_child(self.parent_box, b); } some(b) => BTree.add_child(self.parent_box, b)
} }
self.anon_box = none; self.anon_box = none;
} }
@ -162,14 +160,12 @@ impl box_builder_priv of box_builder_priv for Node {
"] "]
fn determine_box_kind() -> BoxKind { fn determine_box_kind() -> BoxKind {
alt self.read(|n| copy n.kind) { alt self.read(|n| copy n.kind) {
~Text(string) { ~Text(string) => TextBox(@text_box(copy string)),
TextBox(@text_box(copy string)) ~Element(element) => {
}
~Element(element) {
alt *element.kind { alt *element.kind {
HTMLDivElement { BlockBox } HTMLDivElement => BlockBox,
HTMLImageElement({size}) { IntrinsicBox(@size) } HTMLImageElement({size}) => IntrinsicBox(@size),
UnknownElement { InlineBox } UnknownElement => InlineBox
} }
} }
} }
@ -186,11 +182,11 @@ impl box_builder_methods of box_builder_methods for Node {
let box_kind = self.determine_box_kind(); let box_kind = self.determine_box_kind();
let my_box = @Box(self, box_kind); let my_box = @Box(self, box_kind);
alt box_kind { alt box_kind {
BlockBox | InlineBox { BlockBox | InlineBox => {
let cx = create_context(self, my_box); let cx = create_context(self, my_box);
cx.construct_boxes_for_children(); cx.construct_boxes_for_children();
} }
_ { _ => {
// Nothing to do. // Nothing to do.
} }
} }

View file

@ -65,7 +65,7 @@ Creates a display list item for a single block.
* `origin` - The coordinates of upper-left corner of the passed in box. * `origin` - The coordinates of upper-left corner of the passed in box.
"] "]
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn box_to_display_items(list: dl::display_list, box: @Box, origin: Point2D<au>) { fn box_to_display_items(list: dl::display_list, box: @Box, origin: Point2D<au>) {
#debug("request to display a box from origin %?", origin); #debug("request to display a box from origin %?", origin);
@ -73,7 +73,7 @@ fn box_to_display_items(list: dl::display_list, box: @Box, origin: Point2D<au>)
let col = box.appearance.background_color; let col = box.appearance.background_color;
alt box.kind { alt box.kind {
TextBox(subbox) { TextBox(subbox) => {
let run = copy subbox.run; let run = copy subbox.run;
assert run.is_some(); assert run.is_some();
list.push(dl::display_item({ list.push(dl::display_item({
@ -86,7 +86,7 @@ fn box_to_display_items(list: dl::display_list, box: @Box, origin: Point2D<au>)
})); }));
return; return;
} }
_ { _ => {
// Fall through // Fall through
} }
}; };
@ -118,14 +118,16 @@ fn should_convert_text_boxes_to_solid_color_background_items() {
let s = Scope(); let s = Scope();
let n = s.new_node(Text(~"firecracker")); let n = s.new_node(Text(~"firecracker"));
let b = n.construct_boxes(); let b = n.construct_boxes();
let subbox = alt check b.kind { TextBox(subbox) { subbox } };
let subbox = alt check b.kind { TextBox(subbox) => subbox };
b.reflow_text(px_to_au(800), subbox); b.reflow_text(px_to_au(800), subbox);
let list = dvec(); let list = dvec();
box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0))); box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0)));
alt list[0].item_type { alt list[0].item_type {
dl::display_item_solid_color(*) { } dl::display_item_solid_color(*) => { }
_ { fail } _ => { fail }
} }
} }
@ -137,14 +139,16 @@ fn should_convert_text_boxes_to_text_items() {
let s = Scope(); let s = Scope();
let n = s.new_node(Text(~"firecracker")); let n = s.new_node(Text(~"firecracker"));
let b = n.construct_boxes(); let b = n.construct_boxes();
let subbox = alt check b.kind { TextBox(subbox) { subbox } };
let subbox = alt check b.kind { TextBox(subbox) => { subbox } };
b.reflow_text(px_to_au(800), subbox); b.reflow_text(px_to_au(800), subbox);
let list = dvec(); let list = dvec();
box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0))); box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0)));
alt list[1].item_type { alt list[1].item_type {
dl::display_item_text(_) { } dl::display_item_text(_) => { }
_ { fail } _ => { fail }
} }
} }
@ -155,7 +159,9 @@ fn should_calculate_the_bounds_of_the_text_box_background_color() {
let s = Scope(); let s = Scope();
let n = s.new_node(Text(~"firecracker")); let n = s.new_node(Text(~"firecracker"));
let b = n.construct_boxes(); let b = n.construct_boxes();
let subbox = alt check b.kind { TextBox(subbox) { subbox } };
let subbox = alt check b.kind { TextBox(subbox) => { subbox } };
b.reflow_text(px_to_au(800), subbox); b.reflow_text(px_to_au(800), subbox);
let list = dvec(); let list = dvec();
box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0))); box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0)));
@ -175,7 +181,9 @@ fn should_calculate_the_bounds_of_the_text_items() {
let s = Scope(); let s = Scope();
let n = s.new_node(Text(~"firecracker")); let n = s.new_node(Text(~"firecracker"));
let b = n.construct_boxes(); let b = n.construct_boxes();
let subbox = alt check b.kind { TextBox(subbox) { subbox } };
let subbox = alt check b.kind { TextBox(subbox) => { subbox } };
b.reflow_text(px_to_au(800), subbox); b.reflow_text(px_to_au(800), subbox);
let list = dvec(); let list = dvec();
box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0))); box_to_display_items(list, b, Point2D(px_to_au(0), px_to_au(0)));

View file

@ -21,41 +21,39 @@ import comm::*;
type Layout = chan<Msg>; type Layout = chan<Msg>;
enum Msg { enum Msg {
BuildMsg(Node, Stylesheet), BuildMsg(Node, arc<Stylesheet>),
PingMsg(chan<content::PingMsg>), PingMsg(chan<content::PingMsg>),
ExitMsg ExitMsg
} }
fn Layout(renderer: Renderer) -> Layout { fn Layout(renderer: Renderer) -> Layout {
spawn_listener::<Msg>(|request| { do spawn_listener::<Msg>|request| {
loop { loop {
alt request.recv() { alt request.recv() {
PingMsg(ping_channel) { PingMsg(ping_channel) => ping_channel.send(content::PongMsg),
ping_channel.send(content::PongMsg); ExitMsg => {
} #debug("layout: ExitMsg received");
ExitMsg { break;
#debug("layout: ExitMsg received"); }
break; BuildMsg(node, styles) => {
} #debug("layout: received layout request for:");
BuildMsg(node, styles) { node.dump();
#debug("layout: received layout request for:");
node.dump(); do util::time::time(~"layout") {
node.initialize_style_for_subtree();
do util::time::time(~"layout") { node.recompute_style_for_subtree(styles);
node.initialize_style_for_subtree();
node.recompute_style_for_subtree(arc(copy styles)); let this_box = node.construct_boxes();
this_box.dump();
let this_box = node.construct_boxes();
this_box.dump(); this_box.apply_css_style();
this_box.reflow(px_to_au(800));
this_box.apply_css_style();
this_box.reflow(px_to_au(800)); let dlist = build_display_list(this_box);
renderer.send(renderer::RenderMsg(dlist));
let dlist = build_display_list(this_box);
renderer.send(renderer::RenderMsg(dlist));
}
} }
}
} }
} }
}) }
} }

View file

@ -34,16 +34,16 @@ impl ApplyStyleBoxMethods of ApplyStyleBoxMethods for @Box {
// Right now, we only handle images. // Right now, we only handle images.
do self.node.read |node| { do self.node.read |node| {
alt node.kind { alt node.kind {
~Element(element) { ~Element(element) => {
let style = self.node.get_specified_style(); let style = self.node.get_specified_style();
self.appearance.background_color = alt style.background_color { self.appearance.background_color = alt style.background_color {
some(col) { col } some(col) => col,
none { node.kind.default_color() } none => node.kind.default_color()
}; };
alt element.kind { alt element.kind {
~HTMLImageElement(*) { ~HTMLImageElement(*) => {
let url = element.get_attr(~"src"); let url = element.get_attr(~"src");
if url.is_some() { if url.is_some() {
@ -52,10 +52,10 @@ impl ApplyStyleBoxMethods of ApplyStyleBoxMethods for @Box {
self.appearance.background_image = some(ImageHolder(option::unwrap(url))) self.appearance.background_image = some(ImageHolder(option::unwrap(url)))
}; };
} }
_ { /* Ignore. */ } _ => { /* Ignore. */ }
} }
} }
_ { /* Ignore. */ } _ => { /* Ignore. */ }
} }
} }
} }

View file

@ -14,41 +14,41 @@ export matching_methods;
#[doc="Check if a CSS attribute matches the attribute of an HTML element."] #[doc="Check if a CSS attribute matches the attribute of an HTML element."]
fn attrs_match(attr: Attr, elmt: ElementData) -> bool { fn attrs_match(attr: Attr, elmt: ElementData) -> bool {
alt attr { alt attr {
Exists(name) { Exists(name) => {
alt elmt.get_attr(name) { alt elmt.get_attr(name) {
some(_) { return true; } some(_) => true,
none { return false; } none => false
} }
} }
Exact(name, val) { Exact(name, val) => {
alt elmt.get_attr(name) { alt elmt.get_attr(name) {
some(value) { return value == val; } some(value) => value == val,
none { return false; } none => false
} }
} }
Includes(name, val) { Includes(name, val) => {
// Comply with css spec, if the specified attribute is empty // Comply with css spec, if the specified attribute is empty
// it cannot match. // it cannot match.
if val == ~"" { return false; } if val == ~"" { return false; }
alt elmt.get_attr(name) { alt elmt.get_attr(name) {
some(value) { return value.split_char(' ').contains(val); } some(value) => value.split_char(' ').contains(val),
none { return false; } none => false
} }
} }
StartsWith(name, val) { StartsWith(name, val) => {
alt elmt.get_attr(name) { alt elmt.get_attr(name) {
some(value) { some(value) => {
//check that there is only one attribute value and it //check that there is only one attribute value and it
//starts with the perscribed value //starts with the perscribed value
if !value.starts_with(val) || value.contains(~" ") { return false; } if !value.starts_with(val) || value.contains(~" ") { return false; }
// We match on either the exact value or value-foo // We match on either the exact value or value-foo
if value.len() == val.len() { return true; } if value.len() == val.len() { true }
else { return value.starts_with(val + ~"-"); } else { value.starts_with(val + ~"-") }
} }
none { none => {
return false; false
} }
} }
} }
@ -67,10 +67,10 @@ impl priv_matching_methods of priv_matching_methods for Node {
"] "]
fn matches_element(sel: ~Selector) -> bool { fn matches_element(sel: ~Selector) -> bool {
alt *sel { alt *sel {
Child(_, _) | Descendant(_, _) | Sibling(_, _) { return false; } Child(_, _) | Descendant(_, _) | Sibling(_, _) => { return false; }
Element(tag, attrs) { Element(tag, attrs) => {
alt self.read(|n| copy *n.kind) { alt self.read(|n| copy *n.kind) {
base::Element(elmt) { base::Element(elmt) => {
if !(tag == ~"*" || tag == elmt.tag_name) { if !(tag == ~"*" || tag == elmt.tag_name) {
return false; return false;
} }
@ -83,7 +83,7 @@ impl priv_matching_methods of priv_matching_methods for Node {
return true; return true;
} }
Text(str) { /*fall through, currently unsupported*/ } Text(str) => { /*fall through, currently unsupported*/ }
} }
} }
} }
@ -95,70 +95,65 @@ impl priv_matching_methods of priv_matching_methods for Node {
#[doc = "Checks if a generic CSS selector matches a given HTML element"] #[doc = "Checks if a generic CSS selector matches a given HTML element"]
fn matches_selector(sel : ~Selector) -> bool { fn matches_selector(sel : ~Selector) -> bool {
alt *sel { alt *sel {
Element(str, atts) { return self.matches_element(sel); } Element(str, atts) => { return self.matches_element(sel); }
Child(sel1, sel2) { Child(sel1, sel2) => {
alt self.read(|n| n.tree.parent) { return alt self.read(|n| n.tree.parent) {
some(parent) { some(parent) => self.matches_element(sel2) && parent.matches_selector(sel1),
return self.matches_element(sel2) && none => false
parent.matches_selector(sel1);
}
none { return false; }
} }
} }
Descendant(sel1, sel2) { Descendant(sel1, sel2) => {
if !self.matches_element(sel2) { if !self.matches_element(sel2) { return false; }
return false;
}
//loop over all ancestors to check if they are the person //loop over all ancestors to check if they are the person
//we should be descended from. //we should be descended from.
let mut cur_parent = alt self.read(|n| n.tree.parent) { let mut cur_parent = alt self.read(|n| n.tree.parent) {
some(parent) { parent } some(parent) => parent,
none { return false; } none => return false
}; };
loop { loop {
if cur_parent.matches_selector(sel1) { return true; } if cur_parent.matches_selector(sel1) { return true; }
cur_parent = alt cur_parent.read(|n| n.tree.parent) { cur_parent = alt cur_parent.read(|n| n.tree.parent) {
some(parent) { parent } some(parent) => parent,
none { return false; } none => return false
}; };
} }
} }
Sibling(sel1, sel2) { Sibling(sel1, sel2) => {
if !self.matches_element(sel2) { return false; } if !self.matches_element(sel2) { return false; }
// Loop over this node's previous siblings to see if they match. // Loop over this node's previous siblings to see if they match.
alt self.read(|n| n.tree.prev_sibling) { alt self.read(|n| n.tree.prev_sibling) {
some(sib) { some(sib) => {
let mut cur_sib = sib; let mut cur_sib = sib;
loop { loop {
if cur_sib.matches_selector(sel1) { return true; } if cur_sib.matches_selector(sel1) { return true; }
cur_sib = alt cur_sib.read(|n| n.tree.prev_sibling) { cur_sib = alt cur_sib.read(|n| n.tree.prev_sibling) {
some(sib) { sib } some(sib) => sib,
none { break; } none => { break; }
}; };
} }
} }
none { } none => { }
} }
// check the rest of the siblings // check the rest of the siblings
alt self.read(|n| n.tree.next_sibling) { alt self.read(|n| n.tree.next_sibling) {
some(sib) { some(sib) => {
let mut cur_sib = sib; let mut cur_sib = sib;
loop { loop {
if cur_sib.matches_selector(sel1) { return true; } if cur_sib.matches_selector(sel1) { return true; }
cur_sib = alt cur_sib.read(|n| n.tree.next_sibling) { cur_sib = alt cur_sib.read(|n| n.tree.next_sibling) {
some(sib) { sib } some(sib) => sib,
none { break; } none => { break; }
}; };
} }
} }
none { } none => { }
} }
return false; return false;
@ -176,13 +171,13 @@ impl priv_style_methods of priv_style_methods for Node {
fn update_style(decl : StyleDeclaration) { fn update_style(decl : StyleDeclaration) {
self.aux(|layout| { self.aux(|layout| {
alt decl { alt decl {
BackgroundColor(col) { layout.specified_style.background_color = some(col); } BackgroundColor(col) => layout.specified_style.background_color = some(col),
Display(dis) { layout.specified_style.display_type = some(dis); } Display(dis) => layout.specified_style.display_type = some(dis),
FontSize(size) { layout.specified_style.font_size = some(size); } FontSize(size) => layout.specified_style.font_size = some(size),
Height(size) { layout.specified_style.height = some(size); } Height(size) => layout.specified_style.height = some(size),
TextColor(col) { layout.specified_style.text_color = some(col); } TextColor(col) => layout.specified_style.text_color = some(col),
Width(size) { layout.specified_style.width = some(size); } Width(size) => layout.specified_style.width = some(size)
} };
}) })
} }
} }
@ -222,7 +217,7 @@ mod test {
import dvec::{dvec, extensions}; import dvec::{dvec, extensions};
import io::println; import io::println;
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn new_node_from_attr(scope: NodeScope, -name: ~str, -val: ~str) -> Node { fn new_node_from_attr(scope: NodeScope, -name: ~str, -val: ~str) -> Node {
let elmt = ElementData(~"div", ~HTMLDivElement); let elmt = ElementData(~"div", ~HTMLDivElement);
let attr = ~Attr(name, val); let attr = ~Attr(name, val);

View file

@ -30,8 +30,8 @@ trait default_style_methods {
impl default_style_methods of default_style_methods for NodeKind { impl default_style_methods of default_style_methods for NodeKind {
fn default_color() -> Color { fn default_color() -> Color {
alt self { alt self {
Text(*) { white() } Text(*) => { white() }
Element(*) { Element(*) => {
let r = rand::rng(); let r = rand::rng();
rgb(r.next() as u8, r.next() as u8, r.next() as u8) rgb(r.next() as u8, r.next() as u8, r.next() as u8)
} }
@ -40,13 +40,13 @@ impl default_style_methods of default_style_methods for NodeKind {
fn default_display_type() -> DisplayType { fn default_display_type() -> DisplayType {
alt self { alt self {
Text(*) { DisInline } Text(*) => { DisInline }
Element(element) { Element(element) => {
alt *element.kind { alt *element.kind {
HTMLDivElement { DisBlock } HTMLDivElement => DisBlock,
HTMLHeadElement { DisNone } HTMLHeadElement => DisNone,
HTMLImageElement(*) { DisInline } HTMLImageElement(*) => DisInline,
UnknownElement { DisInline } UnknownElement => DisInline
} }
} }
} }

View file

@ -24,8 +24,8 @@ trait text_layout_methods {
impl text_layout_methods of text_layout_methods for @Box { impl text_layout_methods of text_layout_methods for @Box {
fn reflow_text(_available_width: au, subbox: @text_box) { fn reflow_text(_available_width: au, subbox: @text_box) {
alt self.kind { alt self.kind {
TextBox(*) { /* ok */ } TextBox(*) => { /* ok */ }
_ { fail ~"expected text box in reflow_text!" } _ => { fail ~"expected text box in reflow_text!" }
}; };
// FIXME: The font library should not be initialized here // FIXME: The font library should not be initialized here
@ -51,7 +51,7 @@ fn should_calculate_the_size_of_the_text_box() {
let n = s.new_node(Text(~"firecracker")); let n = s.new_node(Text(~"firecracker"));
let b = n.construct_boxes(); let b = n.construct_boxes();
let subbox = alt check b.kind { TextBox(subbox) { subbox } }; let subbox = alt check b.kind { TextBox(subbox) => { subbox } };
b.reflow_text(px_to_au(800), subbox); b.reflow_text(px_to_au(800), subbox);
let expected = Size2D(px_to_au(84), px_to_au(20)); let expected = Size2D(px_to_au(84), px_to_au(20));
assert b.bounds.size == expected; assert b.bounds.size == expected;

View file

@ -88,7 +88,7 @@ fn traverse_helper(-root : @Box, -top_down : fn~(@Box), -bottom_up : fn~(@Box))
} }
#[doc="A noneffectful function to be used if only one pass is required."] #[doc="A noneffectful function to be used if only one pass is required."]
fn nop(box : @Box) { fn nop(_box : @Box) {
return; return;
} }

View file

@ -15,7 +15,7 @@ enum RenderMode {
Png(~str) Png(~str)
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn from_cmdline_args(args: ~[~str]) -> Opts { fn from_cmdline_args(args: ~[~str]) -> Opts {
import std::getopts; import std::getopts;
@ -26,8 +26,8 @@ fn from_cmdline_args(args: ~[~str]) -> Opts {
]; ];
let opt_match = alt getopts::getopts(args, opts) { let opt_match = alt getopts::getopts(args, opts) {
result::ok(m) { copy m } result::ok(m) => { copy m }
result::err(f) { fail getopts::fail_str(f) } result::err(f) => { fail getopts::fail_str(f) }
}; };
let urls = if opt_match.free.is_empty() { let urls = if opt_match.free.is_empty() {
@ -37,8 +37,8 @@ fn from_cmdline_args(args: ~[~str]) -> Opts {
}; };
let render_mode = alt getopts::opt_maybe_str(opt_match, ~"o") { let render_mode = alt getopts::opt_maybe_str(opt_match, ~"o") {
some(output_file) { Png(copy output_file) } some(output_file) => { Png(copy output_file) }
none { Screen } none => { Screen }
}; };
{ {

View file

@ -27,8 +27,8 @@ trait util_methods {
impl util_methods of util_methods for TokenReader { impl util_methods of util_methods for TokenReader {
fn get() -> Token { fn get() -> Token {
alt copy self.lookahead { alt copy self.lookahead {
some(tok) { self.lookahead = none; copy tok } some(tok) => { self.lookahead = none; copy tok }
none { self.stream.recv() } none => { self.stream.recv() }
} }
} }
@ -49,9 +49,9 @@ impl parser_methods of parser_methods for TokenReader {
fn parse_element() -> option<~style::Selector> { fn parse_element() -> option<~style::Selector> {
// Get the current element type // Get the current element type
let elmt_name = alt self.get() { let elmt_name = alt self.get() {
Element(tag) { copy tag } Element(tag) => { copy tag }
Eof { return none; } Eof => { return none; }
_ { fail ~"Expected an element" } _ => { fail ~"Expected an element" }
}; };
let mut attr_list = ~[]; let mut attr_list = ~[];
@ -60,15 +60,15 @@ impl parser_methods of parser_methods for TokenReader {
loop { loop {
let tok = self.get(); let tok = self.get();
alt tok { alt tok {
Attr(attr) { push(attr_list, copy attr); } Attr(attr) => { push(attr_list, copy attr); }
StartDescription | Descendant | Child | Sibling | Comma { StartDescription | Descendant | Child | Sibling | Comma => {
self.unget(tok); self.unget(tok);
break; break;
} }
Eof { return none; } Eof => { return none; }
Element(_) { fail ~"Unexpected second element without relation to first element"; } Element(_) => fail ~"Unexpected second element without relation to first element",
EndDescription { fail ~"Unexpected '}'"; } EndDescription => fail ~"Unexpected '}'",
Description(_, _) { fail ~"Unexpected description"; } Description(_, _) => fail ~"Unexpected description"
} }
} }
return some(~style::Element(elmt_name, attr_list)); return some(~style::Element(elmt_name, attr_list));
@ -82,8 +82,8 @@ impl parser_methods of parser_methods for TokenReader {
let mut cur_sel; let mut cur_sel;
alt self.parse_element() { alt self.parse_element() {
some(elmt) { cur_sel = copy elmt; } some(elmt) => { cur_sel = copy elmt; }
none { return none; } // we hit an eof in the middle of a rule none => { return none; } // we hit an eof in the middle of a rule
} }
loop { loop {
@ -91,47 +91,47 @@ impl parser_methods of parser_methods for TokenReader {
let built_sel <- cur_sel; let built_sel <- cur_sel;
alt tok { alt tok {
Descendant { Descendant => {
alt self.parse_element() { alt self.parse_element() {
some(elmt) { some(elmt) => {
let new_sel = copy elmt; let new_sel = copy elmt;
cur_sel <- ~style::Descendant(built_sel, new_sel) cur_sel <- ~style::Descendant(built_sel, new_sel)
} }
none { return none; } none => { return none; }
} }
} }
Child { Child => {
alt self.parse_element() { alt self.parse_element() {
some(elmt) { some(elmt) => {
let new_sel = copy elmt; let new_sel = copy elmt;
cur_sel <- ~style::Child(built_sel, new_sel) cur_sel <- ~style::Child(built_sel, new_sel)
} }
none { return none; } none => { return none; }
} }
} }
Sibling { Sibling => {
alt self.parse_element() { alt self.parse_element() {
some(elmt) { some(elmt) => {
let new_sel = copy elmt; let new_sel = copy elmt;
cur_sel <- ~style::Sibling(built_sel, new_sel) cur_sel <- ~style::Sibling(built_sel, new_sel)
} }
none { return none; } none => { return none; }
} }
} }
StartDescription { StartDescription => {
push(sel_list, built_sel); push(sel_list, built_sel);
self.unget(StartDescription); self.unget(StartDescription);
break; break;
} }
Comma { Comma => {
push(sel_list, built_sel); push(sel_list, built_sel);
self.unget(Comma); self.unget(Comma);
break; break;
} }
Attr(_) | EndDescription | Element(_) | Description(_, _) { Attr(_) | EndDescription | Element(_) | Description(_, _) => {
fail #fmt["Unexpected token %? in elements", tok]; fail #fmt["Unexpected token %? in elements", tok];
} }
Eof { return none; } Eof => { return none; }
} }
} }
@ -139,9 +139,9 @@ impl parser_methods of parser_methods for TokenReader {
// TODO: fix this when rust gets labelled loops // TODO: fix this when rust gets labelled loops
let tok = self.get(); let tok = self.get();
alt tok { alt tok {
StartDescription { break; } StartDescription => { break; }
Comma { } Comma => { }
_ { self.unget(tok); } _ => { self.unget(tok); }
} }
} }
@ -155,22 +155,22 @@ impl parser_methods of parser_methods for TokenReader {
loop { loop {
let tok = self.get(); let tok = self.get();
alt tok { alt tok {
EndDescription { break; } EndDescription => { break; }
Description(prop, val) { Description(prop, val) => {
let desc = alt prop { let desc = alt prop {
// TODO: have color parsing return an option instead of a real value // TODO: have color parsing return an option instead of a real value
~"background-color" { parse_color(val).map(|res| BackgroundColor(res)) } ~"background-color" => parse_color(val).map(|res| BackgroundColor(res)),
~"color" { parse_color(val).map(|res| TextColor(res)) } ~"color" => parse_color(val).map(|res| TextColor(res)),
~"display" { parse_display_type(val).map(|res| Display(res)) } ~"display" => parse_display_type(val).map(|res| Display(res)),
~"font-size" { parse_font_size(val).map(|res| FontSize(res)) } ~"font-size" => parse_font_size(val).map(|res| FontSize(res)),
~"height" { parse_size(val).map(|res| Height(res)) } ~"height" => parse_size(val).map(|res| Height(res)),
~"width" { parse_size(val).map(|res| Width(res)) } ~"width" => parse_size(val).map(|res| Width(res)),
_ { #debug["Recieved unknown style property '%s'", val]; none } _ => { #debug["Recieved unknown style property '%s'", val]; none }
}; };
desc.map(|res| push(desc_list, res)); desc.map(|res| push(desc_list, res));
} }
Eof { return none; } Eof => { return none; }
StartDescription | Descendant | Child | Sibling | Comma | Element(_) | Attr(_) { StartDescription | Descendant | Child | Sibling | Comma | Element(_) | Attr(_) => {
fail #fmt["Unexpected token %? in description", tok]; fail #fmt["Unexpected token %? in description", tok];
} }
} }
@ -180,17 +180,18 @@ impl parser_methods of parser_methods for TokenReader {
} }
fn parse_rule() -> option<~style::Rule> { fn parse_rule() -> option<~style::Rule> {
// TODO: get rid of copies once alt move works
let sel_list = alt self.parse_selector() { let sel_list = alt self.parse_selector() {
some(list){ copy list } some(list) => { copy list }
none { return none; } none => { return none; }
}; };
#debug("sel_list: %?", sel_list); #debug("sel_list: %?", sel_list);
// Get the description to be applied to the selector // Get the description to be applied to the selector
let desc_list = alt self.parse_description() { let desc_list = alt self.parse_description() {
some(list) { copy list } some(list) => { copy list }
none { return none; } none => { return none; }
}; };
#debug("desc_list: %?", desc_list); #debug("desc_list: %?", desc_list);
@ -205,8 +206,8 @@ fn build_stylesheet(+stream : pipes::port<Token>) -> ~[~style::Rule] {
loop { loop {
alt reader.parse_rule() { alt reader.parse_rule() {
some(rule) { push(rule_list, copy rule); } some(rule) => { push(rule_list, copy rule); }
none { break; } none => { break; }
} }
} }

View file

@ -50,15 +50,15 @@ impl css_methods of css_methods for CssLexer {
fn parse_css() -> Token { fn parse_css() -> Token {
let mut ch: u8; let mut ch: u8;
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c; } CoeChar(c) => ch = c,
CoeEof { return Eof; } CoeEof => { return Eof; }
} }
let token = alt self.parser_state { let token = alt self.parser_state {
CssDescription { self.parse_css_description(ch) } CssDescription => self.parse_css_description(ch),
CssAttribute { self.parse_css_attribute(ch) } CssAttribute => self.parse_css_attribute(ch),
CssElement { self.parse_css_element(ch) } CssElement => self.parse_css_element(ch),
CssRelation { self.parse_css_relation(ch) } CssRelation => self.parse_css_relation(ch)
}; };
#debug["token=%?", token]; #debug["token=%?", token];
@ -69,11 +69,11 @@ impl css_methods of css_methods for CssLexer {
self.parser_state = CssElement; self.parser_state = CssElement;
let token = alt c { let token = alt c {
'{' as u8 { self.parser_state = CssDescription; StartDescription } '{' as u8 => { self.parser_state = CssDescription; StartDescription }
'>' as u8 { Child } '>' as u8 => { Child }
'+' as u8 { Sibling } '+' as u8 => { Sibling }
',' as u8 { Comma } ',' as u8 => { Comma }
_ { self.input_state.unget(c); Descendant } _ => { self.input_state.unget(c); Descendant }
}; };
self.input_state.eat_whitespace(); self.input_state.eat_whitespace();
@ -113,22 +113,22 @@ impl css_methods of css_methods for CssLexer {
self.input_state.eat_whitespace(); self.input_state.eat_whitespace();
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c } CoeChar(c) => { ch = c }
CoeEof { fail ~"File ended before description of style" } CoeEof => { fail ~"File ended before description of style" }
} }
return self.parse_css_relation(ch); return self.parse_css_relation(ch);
} }
alt ch { alt ch {
'.' as u8 { return Attr(style::Includes(~"class", self.input_state.parse_ident())); } '.' 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(style::Includes(~"id", self.input_state.parse_ident())),
'[' as u8 { '[' as u8 => {
let attr_name = self.input_state.parse_ident(); let attr_name = self.input_state.parse_ident();
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c; } CoeChar(c) => { ch = c; }
CoeEof { fail ~"File ended before description finished"; } CoeEof => { fail ~"File ended before description finished"; }
} }
if ch == ']' as u8 { if ch == ']' as u8 {
@ -151,7 +151,7 @@ impl css_methods of css_methods for CssLexer {
fail #fmt("Unexpected symbol %c in attribute", ch as char); fail #fmt("Unexpected symbol %c in attribute", ch as char);
} }
_ { fail #fmt("Unexpected symbol %c in attribute", ch as char); } _ => { fail #fmt("Unexpected symbol %c in attribute", ch as char); }
} }
} }
@ -166,8 +166,8 @@ impl css_methods of css_methods for CssLexer {
self.input_state.eat_whitespace(); self.input_state.eat_whitespace();
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c } CoeChar(c) => { ch = c }
CoeEof { fail ~"Reached end of file in CSS description" } CoeEof => { fail ~"Reached end of file in CSS description" }
} }
} }
@ -188,8 +188,8 @@ impl css_methods of css_methods for CssLexer {
} }
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c } CoeChar(c) => { ch = c }
CoeEof { fail ~"Reached end of file in CSS description" } CoeEof => { fail ~"Reached end of file in CSS description" }
} }
} }
@ -199,8 +199,8 @@ impl css_methods of css_methods for CssLexer {
// Get the value of the descriptor // Get the value of the descriptor
loop { loop {
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c } CoeChar(c) => { ch = c }
CoeEof { fail ~"Reached end of file in CSS description" } CoeEof => { fail ~"Reached end of file in CSS description" }
} }
if ch.is_whitespace() { if ch.is_whitespace() {
@ -259,7 +259,6 @@ fn spawn_css_lexer_from_string(-content : ~str) -> pipes::port<Token> {
do task::spawn { do task::spawn {
let input_port = comm::port(); let input_port = comm::port();
let chan = input_port.chan();
input_port.send(Payload(str::bytes(content))); input_port.send(Payload(str::bytes(content)));
input_port.send(Done(ok(()))); input_port.send(Done(ok(())));
@ -269,17 +268,18 @@ fn spawn_css_lexer_from_string(-content : ~str) -> pipes::port<Token> {
return result_port; return result_port;
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn spawn_css_lexer_task(-url: url, resource_task: ResourceTask) -> pipes::port<Token> { fn spawn_css_lexer_task(-url: url, resource_task: ResourceTask) -> pipes::port<Token> {
let (result_chan, result_port) = pipes::stream(); let (result_chan, result_port) = pipes::stream();
task::spawn(|| { do task::spawn || {
assert url.path.ends_with(".css"); assert url.path.ends_with(".css");
let input_port = port(); let input_port = port();
resource_task.send(Load(url, input_port.chan())); // TODO: change copy to move once the compiler permits it
resource_task.send(Load(copy url, input_port.chan()));
lex_css_from_bytes(input_port, result_chan); lex_css_from_bytes(input_port, result_chan);
}); };
return result_port; return result_port;
} }

View file

@ -28,40 +28,40 @@ enum js_message {
js_exit js_exit
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) { fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) {
// TODO: Implement atoms so that we don't always perform string comparisons. // TODO: Implement atoms so that we don't always perform string comparisons.
scope.read(node, |node_contents| { scope.read(node, |node_contents| {
alt *node_contents.kind { alt *node_contents.kind {
Element(element) { Element(element) => {
element.attrs.push(~Attr(copy key, copy value)); element.attrs.push(~Attr(copy key, copy value));
alt *element.kind { alt *element.kind {
HTMLImageElement(img) if key == ~"width" { HTMLImageElement(img) if key == ~"width" => {
alt int::from_str(value) { alt int::from_str(value) {
none { none => {
// Drop on the floor. // Drop on the floor.
} }
some(s) { img.size.width = geometry::px_to_au(s); } some(s) => { img.size.width = geometry::px_to_au(s); }
} }
} }
HTMLImageElement(img) if key == ~"height" { HTMLImageElement(img) if key == ~"height" => {
alt int::from_str(value) { alt int::from_str(value) {
none { none => {
// Drop on the floor. // Drop on the floor.
} }
some(s) { some(s) => {
img.size.height = geometry::px_to_au(s); img.size.height = geometry::px_to_au(s);
} }
} }
} }
HTMLDivElement | HTMLImageElement(*) | HTMLHeadElement | HTMLDivElement | HTMLImageElement(*) | HTMLHeadElement |
HTMLScriptElement | UnknownElement { HTMLScriptElement | UnknownElement => {
// Drop on the floor. // Drop on the floor.
} }
} }
} }
Text(*) { Text(*) => {
fail ~"attempt to link up an attribute to a text node" fail ~"attempt to link up an attribute to a text node"
} }
} }
@ -70,16 +70,15 @@ fn link_up_attribute(scope: NodeScope, node: Node, -key: ~str, -value: ~str) {
fn build_element_kind(tag_name: ~str) -> ~ElementKind { fn build_element_kind(tag_name: ~str) -> ~ElementKind {
alt tag_name { alt tag_name {
~"div" { ~HTMLDivElement } ~"div" => ~HTMLDivElement,
~"img" { ~"img" => {
~HTMLImageElement({ ~HTMLImageElement({ mut size: Size2D(geometry::px_to_au(100),
mut size: Size2D(geometry::px_to_au(100), geometry::px_to_au(100))
geometry::px_to_au(100))
}) })
} }
~"script" { ~HTMLScriptElement } ~"script" => ~HTMLScriptElement,
~"head" { ~HTMLHeadElement } ~"head" => ~HTMLHeadElement,
_ { ~UnknownElement } _ => ~UnknownElement
} }
} }
@ -103,10 +102,13 @@ fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::por
loop { loop {
alt from_parent.recv() { alt from_parent.recv() {
File(url) { File(url) => {
let result_port = comm::port(); let result_port = comm::port();
let result_chan = comm::chan(result_port); let result_chan = comm::chan(result_port);
// TODO: change copy to move once we have alt move
let url = copy url;
task::spawn(|| { 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 css_stream = css_lexer::spawn_css_lexer_task(copy url, resource_task);
let mut css_rules = css_builder::build_stylesheet(css_stream); let mut css_rules = css_builder::build_stylesheet(css_stream);
result_chan.send(css_rules); result_chan.send(css_rules);
@ -114,7 +116,7 @@ fn css_link_listener(to_parent : comm::chan<Stylesheet>, from_parent : comm::por
push(result_vec, result_port); push(result_vec, result_port);
} }
Exit { Exit => {
break; break;
} }
} }
@ -131,24 +133,27 @@ fn js_script_listener(to_parent : comm::chan<~[~[u8]]>, from_parent : comm::port
loop { loop {
alt from_parent.recv() { alt from_parent.recv() {
js_file(url) { js_file(url) => {
let result_port = comm::port(); let result_port = comm::port();
let result_chan = comm::chan(result_port); let result_chan = comm::chan(result_port);
do task::spawn { // TODO: change copy to move once we have alt move
let url = copy url;
do task::spawn || {
let input_port = port(); let input_port = port();
resource_task.send(Load(url, input_port.chan())); // TODO: change copy to move once we can move into closures
resource_task.send(Load(copy url, input_port.chan()));
let mut buf = ~[]; let mut buf = ~[];
loop { loop {
alt input_port.recv() { alt input_port.recv() {
Payload(data) { Payload(data) => {
buf += data; buf += data;
} }
Done(ok(*)) { Done(ok(*)) => {
result_chan.send(buf); result_chan.send(buf);
break; break;
} }
Done(err(*)) { Done(err(*)) => {
#error("error loading script %s", url.to_str()); #error("error loading script %s", url.to_str());
} }
} }
@ -156,7 +161,7 @@ fn js_script_listener(to_parent : comm::chan<~[~[u8]]>, from_parent : comm::port
} }
push(result_vec, result_port); push(result_vec, result_port);
} }
js_exit { js_exit => {
break; break;
} }
} }
@ -166,7 +171,7 @@ fn js_script_listener(to_parent : comm::chan<~[~[u8]]>, from_parent : comm::port
to_parent.send(js_scripts); to_parent.send(js_scripts);
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url, fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url,
resource_task: ResourceTask) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) { resource_task: ResourceTask) -> (Node, comm::port<Stylesheet>, comm::port<~[~[u8]]>) {
// The current reference node. // The current reference node.
@ -191,75 +196,75 @@ fn build_dom(scope: NodeScope, stream: comm::port<Token>, url: url,
loop { loop {
let token = stream.recv(); let token = stream.recv();
alt token { alt token {
parser::Eof { break; } parser::Eof => { break; }
parser::StartOpeningTag(tag_name) { parser::StartOpeningTag(tag_name) => {
#debug["starting tag %s", tag_name]; #debug["starting tag %s", tag_name];
let element_kind = build_element_kind(tag_name); let element_kind = build_element_kind(tag_name);
let new_node = scope.new_node(Element(ElementData(copy tag_name, element_kind))); let new_node = scope.new_node(Element(ElementData(copy tag_name, element_kind)));
scope.add_child(cur_node, new_node); scope.add_child(cur_node, new_node);
cur_node = new_node; cur_node = new_node;
} }
parser::Attr(key, value) { parser::Attr(key, value) => {
#debug["attr: %? = %?", key, value]; #debug["attr: %? = %?", key, value];
link_up_attribute(scope, cur_node, copy key, copy value); link_up_attribute(scope, cur_node, copy key, copy value);
} }
parser::EndOpeningTag { parser::EndOpeningTag => {
#debug("end opening tag"); #debug("end opening tag");
} }
// TODO: Fail more gracefully (i.e. according to the HTML5 // TODO: Fail more gracefully (i.e. according to the HTML5
// spec) if we close more tags than we open. // spec) if we close more tags than we open.
parser::SelfCloseTag { parser::SelfCloseTag => {
//TODO: check for things other than the link tag //TODO: check for things other than the link tag
scope.read(cur_node, |n| { scope.read(cur_node, |n| {
alt *n.kind { alt *n.kind {
Element(elmt) if elmt.tag_name == ~"link" { Element(elmt) if elmt.tag_name == ~"link" => {
alt elmt.get_attr(~"rel") { alt elmt.get_attr(~"rel") {
some(r) if r == ~"stylesheet" { some(r) if r == ~"stylesheet" => {
alt elmt.get_attr(~"href") { alt elmt.get_attr(~"href") {
some(filename) { some(filename) => {
#debug["Linking to a css sheet named: %s", filename]; #debug["Linking to a css sheet named: %s", filename];
// FIXME: Need to base the new url on the current url // FIXME: Need to base the new url on the current url
let new_url = make_url(filename, some(url)); let new_url = make_url(filename, some(copy url));
style_chan.send(File(new_url)); style_chan.send(File(new_url));
} }
none { /* fall through*/ } none => { /* fall through*/ }
} }
} }
_ { /* fall through*/ } _ => { /* fall through*/ }
} }
} }
_ { /* fall through*/ } _ => { /* fall through*/ }
} }
}); });
cur_node = scope.get_parent(cur_node).get(); cur_node = scope.get_parent(cur_node).get();
} }
parser::EndTag(tag_name) { parser::EndTag(tag_name) => {
// TODO: Assert that the closing tag has the right name. // TODO: Assert that the closing tag has the right name.
scope.read(cur_node, |n| { scope.read(cur_node, |n| {
alt *n.kind { alt *n.kind {
Element(elmt) if elmt.tag_name == ~"script" { Element(elmt) if elmt.tag_name == ~"script" => {
alt elmt.get_attr(~"src") { alt elmt.get_attr(~"src") {
some(filename) { some(filename) => {
#debug["Linking to a js script named: %s", filename]; #debug["Linking to a js script named: %s", filename];
let new_url = make_url(filename, some(url)); let new_url = make_url(filename, some(copy url));
js_chan.send(js_file(new_url)); js_chan.send(js_file(new_url));
} }
none { /* fall through */ } none => { /* fall through */ }
} }
} }
_ { /* fall though */ } _ => { /* fall though */ }
} }
}); });
cur_node = scope.get_parent(cur_node).get(); cur_node = scope.get_parent(cur_node).get();
} }
parser::Text(s) if !s.is_whitespace() { parser::Text(s) if !s.is_whitespace() => {
let new_node = scope.new_node(Text(copy s)); let new_node = scope.new_node(Text(copy s));
scope.add_child(cur_node, new_node); scope.add_child(cur_node, new_node);
} }
parser::Text(_) { parser::Text(_) => {
// FIXME: Whitespace should not be ignored. // FIXME: Whitespace should not be ignored.
} }
parser::Doctype { parser::Doctype => {
// TODO: Do something here... // TODO: Do something here...
} }
} }

View file

@ -39,12 +39,12 @@ impl html_methods of html_methods for HtmlLexer {
fn parse_html() -> Token { fn parse_html() -> Token {
let mut ch: u8; let mut ch: u8;
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c; } CoeChar(c) => { ch = c; }
CoeEof { return Eof; } CoeEof => { return Eof; }
} }
let token = alt self.parser_state { let token = alt self.parser_state {
NormalHtml { self.parse_in_normal_state(ch) } NormalHtml => { self.parse_in_normal_state(ch) }
TagHtml { self.parse_in_tag_state(ch) } TagHtml => { self.parse_in_tag_state(ch) }
}; };
#debug["token=%?", token]; #debug["token=%?", token];
@ -55,8 +55,8 @@ impl html_methods of html_methods for HtmlLexer {
let mut ch = c; let mut ch = c;
if ch == ('<' as u8) { if ch == ('<' as u8) {
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { ch = c; } CoeChar(c) => { ch = c; }
CoeEof { self.input_state.parse_err(~"eof after '<'") } CoeEof => { self.input_state.parse_err(~"eof after '<'") }
} }
if ch == ('!' as u8) { if ch == ('!' as u8) {
@ -89,14 +89,14 @@ impl html_methods of html_methods for HtmlLexer {
let mut s: ~[u8] = ~[ch]; let mut s: ~[u8] = ~[ch];
loop { loop {
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { CoeChar(c) => {
if c == ('<' as u8) { if c == ('<' as u8) {
self.input_state.unget(c); self.input_state.unget(c);
return Text(from_bytes(s)); return Text(from_bytes(s));
} }
push(s, c); push(s, c);
} }
CoeEof { return Text(from_bytes(s)); } CoeEof => { return Text(from_bytes(s)); }
} }
} }
} }
@ -111,7 +111,7 @@ impl html_methods of html_methods for HtmlLexer {
if ch == ('/' as u8) { if ch == ('/' as u8) {
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { CoeChar(c) => {
if c == ('>' as u8) { if c == ('>' as u8) {
self.parser_state = NormalHtml; self.parser_state = NormalHtml;
return SelfCloseTag; return SelfCloseTag;
@ -119,7 +119,7 @@ impl html_methods of html_methods for HtmlLexer {
#warn["/ not followed by > in a tag"]; #warn["/ not followed by > in a tag"];
} }
} }
CoeEof { CoeEof => {
#warn["/ not followed by > at end of file"]; #warn["/ not followed by > at end of file"];
} }
} }
@ -133,11 +133,11 @@ impl html_methods of html_methods for HtmlLexer {
let mut attribute_name = ~[ch]; let mut attribute_name = ~[ch];
loop { loop {
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { CoeChar(c) => {
if c == ('=' as u8) { break; } if c == ('=' as u8) { break; }
push(attribute_name, c); push(attribute_name, c);
} }
CoeEof { CoeEof => {
let name = from_bytes(attribute_name); let name = from_bytes(attribute_name);
return Attr(copy name, name); return Attr(copy name, name);
} }
@ -149,11 +149,11 @@ impl html_methods of html_methods for HtmlLexer {
let mut attribute_value = ~[]; let mut attribute_value = ~[];
loop { loop {
alt self.input_state.get() { alt self.input_state.get() {
CoeChar(c) { CoeChar(c) => {
if c == ('"' as u8) { break; } if c == ('"' as u8) { break; }
push(attribute_value, c); push(attribute_value, c);
} }
CoeEof { CoeEof => {
return Attr(from_bytes(attribute_name), from_bytes(attribute_value)); return Attr(from_bytes(attribute_name), from_bytes(attribute_value));
} }
} }
@ -178,14 +178,15 @@ fn lexer(+input_port: port<resource_task::ProgressMsg>, state : ParseState) -> H
}; };
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn spawn_html_lexer_task(-url: url, resource_task: ResourceTask) -> port<Token> { fn spawn_html_lexer_task(-url: url, resource_task: ResourceTask) -> port<Token> {
let html_port = port(); let html_port = port();
let html_chan = chan(html_port); let html_chan = chan(html_port);
task::spawn(|| { task::spawn(|| {
let input_port = port(); let input_port = port();
resource_task.send(Load(url, input_port.chan())); // TODO: change copy to move once we can move into closures
resource_task.send(Load(copy url, input_port.chan()));
let lexer = lexer(input_port, NormalHtml); let lexer = lexer(input_port, NormalHtml);

View file

@ -47,12 +47,12 @@ trait util_methods {
impl util_methods of util_methods for InputState { impl util_methods of util_methods for InputState {
fn get() -> CharOrEof { fn get() -> CharOrEof {
alt copy self.lookahead { alt copy self.lookahead {
some(coe) { some(coe) => {
let rv = coe; let rv = coe;
self.lookahead = none; self.lookahead = none;
return rv; return rv;
} }
none { none => {
/* fall through */ /* fall through */
} }
} }
@ -68,11 +68,12 @@ impl util_methods of util_methods for InputState {
} }
alt self.input_port.recv() { alt self.input_port.recv() {
Payload(data) { Payload(data) => {
self.buffer = data; // TODO: change copy to move once we have alt move
self.buffer = copy data;
return CoeChar(vec::shift(self.buffer)); return CoeChar(vec::shift(self.buffer));
} }
Done(*) { Done(*) => {
self.eof = true; self.eof = true;
return CoeEof; return CoeEof;
} }
@ -90,8 +91,8 @@ impl util_methods of util_methods for InputState {
fn expect(ch: u8) { fn expect(ch: u8) {
alt self.get() { alt self.get() {
CoeChar(c) { if c != ch { self.parse_err(#fmt("expected '%c'", ch as char)); } } CoeChar(c) => { if c != ch { self.parse_err(#fmt("expected '%c'", ch as char)); } }
CoeEof { self.parse_err(#fmt("expected '%c' at eof", ch as char)); } CoeEof => { self.parse_err(#fmt("expected '%c' at eof", ch as char)); }
} }
} }
@ -99,7 +100,7 @@ impl util_methods of util_methods for InputState {
let mut result: ~[u8] = ~[]; let mut result: ~[u8] = ~[];
loop { loop {
alt self.get() { alt self.get() {
CoeChar(c) { CoeChar(c) => {
if (c.is_alpha()) { push(result, c); } if (c.is_alpha()) { push(result, c); }
else if result.len() == 0u { self.parse_err(~"expected ident"); } else if result.len() == 0u { self.parse_err(~"expected ident"); }
else { else {
@ -107,7 +108,7 @@ impl util_methods of util_methods for InputState {
break; break;
} }
} }
CoeEof { CoeEof => {
self.parse_err(~"expected ident"); self.parse_err(~"expected ident");
} }
} }
@ -125,13 +126,13 @@ impl util_methods of util_methods for InputState {
fn eat_whitespace() { fn eat_whitespace() {
loop { loop {
alt self.get() { alt self.get() {
CoeChar(c) { CoeChar(c) => {
if !c.is_whitespace() { if !c.is_whitespace() {
self.unget(c); self.unget(c);
return; return;
} }
} }
CoeEof { CoeEof => {
return; return;
} }
} }

View file

@ -11,16 +11,16 @@ export parse_display_type;
fn parse_unit(str : ~str) -> option<Unit> { fn parse_unit(str : ~str) -> option<Unit> {
alt str { alt str {
s if s.ends_with(~"%") { from_str(str.substr(0, str.len() - 1)).map(|f| Percent(f)) } s if s.ends_with(~"%") => from_str(str.substr(0, str.len() - 1)).map(|f| Percent(f)),
s if s.ends_with(~"in") { from_str(str.substr(0, str.len() - 2)).map(|f| In(f)) } s if s.ends_with(~"in") => from_str(str.substr(0, str.len() - 2)).map(|f| In(f)),
s if s.ends_with(~"cm") { from_str(str.substr(0, str.len() - 2)).map(|f| Cm(f)) } s if s.ends_with(~"cm") => from_str(str.substr(0, str.len() - 2)).map(|f| Cm(f)),
s if s.ends_with(~"mm") { from_str(str.substr(0, str.len() - 2)).map(|f| Mm(f)) } s if s.ends_with(~"mm") => from_str(str.substr(0, str.len() - 2)).map(|f| Mm(f)),
s if s.ends_with(~"pt") { from_str(str.substr(0, str.len() - 2)).map(|f| Pt(f)) } s if s.ends_with(~"pt") => from_str(str.substr(0, str.len() - 2)).map(|f| Pt(f)),
s if s.ends_with(~"pc") { from_str(str.substr(0, str.len() - 2)).map(|f| Pc(f)) } s if s.ends_with(~"pc") => from_str(str.substr(0, str.len() - 2)).map(|f| Pc(f)),
s if s.ends_with(~"px") { from_str(str.substr(0, str.len() - 2)).map(|f| Px(f)) } s if s.ends_with(~"px") => from_str(str.substr(0, str.len() - 2)).map(|f| Px(f)),
s if s.ends_with(~"em") { from_str(str.substr(0, str.len() - 2)).map(|f| Em(f)) } s if s.ends_with(~"em") => from_str(str.substr(0, str.len() - 2)).map(|f| Em(f)),
s if s.ends_with(~"ex") { from_str(str.substr(0, str.len() - 2)).map(|f| Ex(f)) } s if s.ends_with(~"ex") => from_str(str.substr(0, str.len() - 2)).map(|f| Ex(f)),
_ { none } _ => none,
} }
} }
@ -29,35 +29,35 @@ fn parse_font_size(str : ~str) -> option<Unit> {
let default = 16.0; let default = 16.0;
alt str { alt str {
~"xx-small" { some(Px(0.6*default)) } ~"xx-small" => some(Px(0.6*default)),
~"x-small" { some(Px(0.75*default)) } ~"x-small" => some(Px(0.75*default)),
~"small" { some(Px(8.0/9.0*default)) } ~"small" => some(Px(8.0/9.0*default)),
~"medium" { some(Px(default)) } ~"medium" => some(Px(default)),
~"large" { some(Px(1.2*default)) } ~"large" => some(Px(1.2*default)),
~"x-large" { some(Px(1.5*default)) } ~"x-large" => some(Px(1.5*default)),
~"xx-large" { some(Px(2.0*default)) } ~"xx-large" => some(Px(2.0*default)),
~"smaller" { some(Em(0.8)) } ~"smaller" => some(Em(0.8)),
~"larger" { some(Em(1.25)) } ~"larger" => some(Em(1.25)),
~"inherit" { some(Em(1.0)) } ~"inherit" => some(Em(1.0)),
_ { parse_unit(str) } _ => parse_unit(str),
} }
} }
// For width / height, and anything else with the same attribute values // For width / height, and anything else with the same attribute values
fn parse_size(str : ~str) -> option<Unit> { fn parse_size(str : ~str) -> option<Unit> {
alt str { alt str {
~"auto" { some(Auto) } ~"auto" => some(Auto),
~"inherit" { some(Em(1.0)) } ~"inherit" => some(Em(1.0)),
_ { parse_unit(str) } _ => parse_unit(str),
} }
} }
fn parse_display_type(str : ~str) -> option<DisplayType> { fn parse_display_type(str : ~str) -> option<DisplayType> {
alt str { alt str {
~"inline" { some(DisInline) } ~"inline" => some(DisInline),
~"block" { some(DisBlock) } ~"block" => some(DisBlock),
~"none" { some(DisNone) } ~"none" => some(DisNone),
_ { #debug["Recieved unknown display value '%s'", str]; none } _ => { #debug["Recieved unknown display value '%s'", str]; none }
} }
} }

View file

@ -71,16 +71,10 @@ fn mainloop(po: port<Msg>) {
#debug("osmain: peeking"); #debug("osmain: peeking");
while po.peek() { while po.peek() {
alt po.recv() { alt po.recv() {
AddKeyHandler(key_ch) { AddKeyHandler(key_ch) => key_handlers.push(#move(key_ch)),
key_handlers.push(#move(key_ch)); AddEventListener(event_listener) => event_listeners.push(event_listener),
} BeginDrawing(sender) => lend_surface(*surfaces, sender),
AddEventListener(event_listener) { Draw(sender, dt) => {
event_listeners.push(event_listener);
}
BeginDrawing(sender) {
lend_surface(*surfaces, sender);
}
Draw(sender, dt) {
#debug("osmain: received new frame"); #debug("osmain: received new frame");
return_surface(*surfaces, dt); return_surface(*surfaces, dt);
lend_surface(*surfaces, sender); lend_surface(*surfaces, sender);
@ -95,7 +89,7 @@ fn mainloop(po: port<Msg>) {
@layers::layers::Image(800, 600, layers::layers::ARGB32Format, image_data); @layers::layers::Image(800, 600, layers::layers::ARGB32Format, image_data);
image_layer.set_image(image); image_layer.set_image(image);
} }
exit { exit => {
*done = true; *done = true;
} }
} }

View file

@ -14,16 +14,16 @@ fn factory(url: url, progress_chan: chan<ProgressMsg>) {
do spawn { do spawn {
alt file_reader(url.path) { alt file_reader(url.path) {
ok(reader) { ok(reader) => {
while !reader.eof() { while !reader.eof() {
let data = reader.read_bytes(READ_SIZE); let data = reader.read_bytes(READ_SIZE);
progress_chan.send(Payload(data)); progress_chan.send(Payload(data));
} }
progress_chan.send(Done(ok(()))); progress_chan.send(Done(ok(())));
} }
err(*) { err(*) => {
progress_chan.send(Done(err(()))); progress_chan.send(Done(err(())));
} }
}; };
} }
} }

View file

@ -11,19 +11,22 @@ fn factory(url: url, progress_chan: chan<ProgressMsg>) {
assert url.scheme == ~"http"; assert url.scheme == ~"http";
do spawn { do spawn {
#debug("http_loader: requesting via http: %?", url); let url = copy url;
let request = uv_http_request(url);
#debug("http_loader: requesting via http: %?", copy url);
let request = uv_http_request(copy url);
let errored = @mut false; let errored = @mut false;
do request.begin |event| { do request.begin |event| {
let url = copy url;
alt event { alt event {
http_client::Status(*) { } http_client::Status(*) => { }
http_client::Payload(data) { http_client::Payload(data) => {
#debug("http_loader: got data from %?", url); #debug("http_loader: got data from %?", url);
let mut crap = none; let mut crap = none;
*data <-> crap; *data <-> crap;
progress_chan.send(Payload(option::unwrap(crap))); progress_chan.send(Payload(option::unwrap(crap)));
} }
http_client::Error(*) { http_client::Error(*) => {
#debug("http_loader: error loading %?", url); #debug("http_loader: error loading %?", url);
*errored = true; *errored = true;
progress_chan.send(Done(err(()))); progress_chan.send(Done(err(())));

View file

@ -50,7 +50,8 @@ fn ResourceTask() -> ResourceTask {
fn create_resource_task_with_loaders(+loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask { fn create_resource_task_with_loaders(+loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
do spawn_listener |from_client| { do spawn_listener |from_client| {
ResourceManager(from_client, loaders).start() // TODO: change copy to move once we can move into closures
ResourceManager(from_client, copy loaders).start()
} }
} }
@ -59,7 +60,7 @@ class ResourceManager {
/// Per-scheme resource loaders /// Per-scheme resource loaders
let loaders: ~[(~str, LoaderTaskFactory)]; let loaders: ~[(~str, LoaderTaskFactory)];
new(from_client: port<ControlMsg>, loaders: ~[(~str, LoaderTaskFactory)]) { new(from_client: port<ControlMsg>, -loaders: ~[(~str, LoaderTaskFactory)]) {
self.from_client = from_client; self.from_client = from_client;
self.loaders = loaders; self.loaders = loaders;
} }
@ -67,10 +68,10 @@ class ResourceManager {
fn start() { fn start() {
loop { loop {
alt self.from_client.recv() { alt self.from_client.recv() {
Load(url, progress_chan) { Load(url, progress_chan) => {
self.load(url, progress_chan) self.load(url, progress_chan)
} }
Exit { Exit => {
break break
} }
} }
@ -80,11 +81,11 @@ class ResourceManager {
fn load(url: url, progress_chan: chan<ProgressMsg>) { fn load(url: url, progress_chan: chan<ProgressMsg>) {
alt self.get_loader_factory(url) { alt self.get_loader_factory(url) {
some(loader_factory) { some(loader_factory) => {
#debug("resource_task: loading url: %s", url::to_str(url)); #debug("resource_task: loading url: %s", url::to_str(url));
loader_factory(url, progress_chan); loader_factory(url, progress_chan);
} }
none { none => {
#debug("resource_task: no loader for scheme %s", url.scheme); #debug("resource_task: no loader for scheme %s", url.scheme);
progress_chan.send(Done(err(()))); progress_chan.send(Done(err(())));
} }
@ -93,7 +94,7 @@ class ResourceManager {
fn get_loader_factory(url: url) -> option<LoaderTaskFactory> { fn get_loader_factory(url: url) -> option<LoaderTaskFactory> {
for self.loaders.each |scheme_loader| { for self.loaders.each |scheme_loader| {
let (scheme, loader_factory) = scheme_loader; let (scheme, loader_factory) = copy scheme_loader;
if scheme == url.scheme { if scheme == url.scheme {
return some(loader_factory); return some(loader_factory);
} }
@ -109,21 +110,23 @@ fn test_exit() {
} }
#[test] #[test]
#[allow(non_implicitly_copyable_typarams)]
fn test_bad_scheme() { fn test_bad_scheme() {
let resource_task = ResourceTask(); let resource_task = ResourceTask();
let progress = port(); let progress = port();
resource_task.send(Load(url::from_str(~"bogus://whatever").get(), progress.chan())); resource_task.send(Load(url::from_str(~"bogus://whatever").get(), progress.chan()));
alt check progress.recv() { alt check progress.recv() {
Done(result) { assert result.is_err() } Done(result) => { assert result.is_err() }
} }
resource_task.send(Exit); resource_task.send(Exit);
} }
#[test] #[test]
#[allow(non_implicitly_copyable_typarams)]
fn should_delegate_to_scheme_loader() { fn should_delegate_to_scheme_loader() {
let payload = ~[1, 2, 3]; let payload = ~[1, 2, 3];
let loader_factory = fn~(url: url, progress_chan: chan<ProgressMsg>) { let loader_factory = fn~(_url: url, progress_chan: chan<ProgressMsg>) {
progress_chan.send(Payload(payload)); progress_chan.send(Payload(copy payload));
progress_chan.send(Done(ok(()))); progress_chan.send(Done(ok(())));
}; };
let loader_factories = ~[(~"snicklefritz", loader_factory)]; let loader_factories = ~[(~"snicklefritz", loader_factory)];

View file

@ -103,7 +103,7 @@ mod util {
mod url; mod url;
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
mod content { mod content {
} }

View file

@ -14,13 +14,11 @@ fn main(args: ~[~str]) {
run(opts::from_cmdline_args(args)) run(opts::from_cmdline_args(args))
} }
#[warn(no_non_implicitly_copyable_typarams)] #[allow(non_implicitly_copyable_typarams)]
fn run(opts: Opts) { fn run(opts: Opts) {
alt opts.render_mode { alt opts.render_mode {
Screen { Screen => run_pipeline_screen(opts.urls),
run_pipeline_screen(opts.urls) Png(outfile) => {
}
Png(outfile) {
assert opts.urls.is_not_empty(); assert opts.urls.is_not_empty();
if opts.urls.len() > 1u { if opts.urls.len() > 1u {
fail ~"servo asks that you stick to a single URL in PNG output mode" fail ~"servo asks that you stick to a single URL in PNG output mode"
@ -48,9 +46,10 @@ fn run_pipeline_screen(urls: ~[~str]) {
#debug["master: Sending url `%s`", url_to_str(url)]; #debug["master: Sending url `%s`", url_to_str(url)];
engine_chan.send(LoadURLMsg(url)); engine_chan.send(LoadURLMsg(url));
#debug["master: Waiting for keypress"]; #debug["master: Waiting for keypress"];
alt keypress_from_osmain.try_recv() { alt keypress_from_osmain.try_recv() {
some(*) { } some(*) => { }
none { #error("keypress stream closed unexpectedly") } none => { #error("keypress stream closed unexpectedly") }
}; };
} }
@ -76,12 +75,12 @@ fn run_pipeline_png(-url: ~str, outfile: ~str) {
let engine = Engine(sink); let engine = Engine(sink);
let engine_chan = engine.start(); let engine_chan = engine.start();
engine_chan.send(LoadURLMsg(make_url(url, none))); engine_chan.send(LoadURLMsg(make_url(url, none)));
alt buffered_file_writer(outfile) { alt buffered_file_writer(outfile) {
ok(writer) { ok(writer) => writer.write(pngdata_from_sink.recv()),
writer.write(pngdata_from_sink.recv()) err(e) => fail e
}
err(e) { fail e }
} }
let (exit_chan, exit_response_from_engine) = pipes::stream(); let (exit_chan, exit_response_from_engine) = pipes::stream();
engine_chan.send(engine::ExitMsg(exit_chan)); engine_chan.send(engine::ExitMsg(exit_chan));
exit_response_from_engine.recv(); exit_response_from_engine.recv();

View file

@ -102,14 +102,14 @@ class Font {
1 as c_int, addr_of(extents)); 1 as c_int, addr_of(extents));
alt cairo_scaled_font_status(self.cairo_font) { alt cairo_scaled_font_status(self.cairo_font) {
status if status == CAIRO_STATUS_SUCCESS { status if status == CAIRO_STATUS_SUCCESS => {
#debug("x_advance: %?", extents.x_advance); #debug("x_advance: %?", extents.x_advance);
#debug("y_advance: %?", extents.y_advance); #debug("y_advance: %?", extents.y_advance);
return extents.x_advance as int; return extents.x_advance as int;
} }
status { status => {
import str::unsafe::from_c_str; import str::unsafe::from_c_str;
let status_cstr = cairo_status_to_string(status); let status_cstr = cairo_status_to_string(status);

View file

@ -68,7 +68,7 @@ class FreeTypeNativeFont/& {
fn create(lib: FT_Library, buf: &~[u8]) -> result<FreeTypeNativeFont, ()> { fn create(lib: FT_Library, buf: &~[u8]) -> result<FreeTypeNativeFont, ()> {
assert lib.is_not_null(); assert lib.is_not_null();
let face: FT_Face = null(); let face: FT_Face = null();
return vec_as_buf(*buf, |cbuf, len| { return vec_as_buf(*buf, |cbuf, _len| {
if FT_New_Memory_Face(lib, cbuf, (*buf).len() as FT_Long, if FT_New_Memory_Face(lib, cbuf, (*buf).len() as FT_Long,
0 as FT_Long, addr_of(face)).succeeded() { 0 as FT_Long, addr_of(face)).succeeded() {
// FIXME: These values are placeholders // FIXME: These values are placeholders

View file

@ -112,13 +112,13 @@ extern fn glyph_func(_font: *hb_font_t,
assert font.is_not_null(); assert font.is_not_null();
return alt (*font).glyph_idx(unicode as char) { return alt (*font).glyph_idx(unicode as char) {
some(g) { some(g) => {
*glyph = g as hb_codepoint_t; *glyph = g as hb_codepoint_t;
true true
} }
none { none => {
false false
} }
} as hb_bool_t; } as hb_bool_t;
} }

View file

@ -37,11 +37,11 @@ fn hsla(h : float, s : float, l : float, a : float) -> Color {
let h = if h < 0.0 { h + 1.0 } else if h > 1.0 { h - 1.0 } else { h }; let h = if h < 0.0 { h + 1.0 } else if h > 1.0 { h - 1.0 } else { h };
alt h { alt h {
0.0 to 1.0/6.0 { return m1 + (m2 - m1)*h*6.0; } 0.0 to 1.0/6.0 => m1 + (m2 - m1)*h*6.0,
1.0/6.0 to 1.0/2.0 { return m2; } 1.0/6.0 to 1.0/2.0 => m2,
1.0/2.0 to 2.0/3.0 { return m1 + (m2 - m1)*(4.0 - 6.0*h); } 1.0/2.0 to 2.0/3.0 => m1 + (m2 - m1)*(4.0 - 6.0*h),
2.0/3.0 to 1.0 { return m1; } 2.0/3.0 to 1.0 => return m1,
_ { fail ~"unexpected hue value"; } _ => fail ~"unexpected hue value"
} }
} }
@ -74,24 +74,24 @@ mod parsing {
#[doc="Match an exact color keyword."] #[doc="Match an exact color keyword."]
fn parse_by_name(color : ~str) -> option<Color> { fn parse_by_name(color : ~str) -> option<Color> {
let col = alt color.to_lower() { let col = alt color.to_lower() {
~"black" { black() } ~"black" => black(),
~"silver" { silver() } ~"silver" => silver(),
~"gray" { gray() } ~"gray" => gray(),
~"grey" { gray() } ~"grey" => gray(),
~"white" { white() } ~"white" => white(),
~"maroon" { maroon() } ~"maroon" => maroon(),
~"red" { red() } ~"red" => red(),
~"purple" { purple() } ~"purple" => purple(),
~"fuchsia" { fuchsia() } ~"fuchsia" => fuchsia(),
~"green" { green() } ~"green" => green(),
~"lime" { lime() } ~"lime" => lime(),
~"olive" { olive() } ~"olive" => olive(),
~"yellow" { yellow() } ~"yellow" => yellow(),
~"navy" { navy() } ~"navy" => navy(),
~"blue" { blue() } ~"blue" => blue(),
~"teal" { teal() } ~"teal" => teal(),
~"aqua" { aqua() } ~"aqua" => aqua(),
_ { return fail_unrecognized(color) } _ => return fail_unrecognized(color)
}; };
return some(col); return some(col);
@ -108,8 +108,8 @@ mod parsing {
alt (u8::from_str(cols[0]), u8::from_str(cols[1]), alt (u8::from_str(cols[0]), u8::from_str(cols[1]),
u8::from_str(cols[2])) { u8::from_str(cols[2])) {
(some(r), some(g), some(b)) { some(rgb(r, g, b)) } (some(r), some(g), some(b)) => { some(rgb(r, g, b)) }
_ { fail_unrecognized(color) } _ => { fail_unrecognized(color) }
} }
} }
@ -124,8 +124,8 @@ mod parsing {
alt (u8::from_str(cols[0]), u8::from_str(cols[1]), alt (u8::from_str(cols[0]), u8::from_str(cols[1]),
u8::from_str(cols[2]), float::from_str(cols[3])) { u8::from_str(cols[2]), float::from_str(cols[3])) {
(some(r), some(g), some(b), some(a)) { some(rgba(r, g, b, a)) } (some(r), some(g), some(b), some(a)) => { some(rgba(r, g, b, a)) }
_ { fail_unrecognized(color) } _ => { fail_unrecognized(color) }
} }
} }
@ -140,8 +140,8 @@ mod parsing {
alt (float::from_str(vals[0]), float::from_str(vals[1]), alt (float::from_str(vals[0]), float::from_str(vals[1]),
float::from_str(vals[2])) { float::from_str(vals[2])) {
(some(h), some(s), some(l)) { some(hsl(h, s, l)) } (some(h), some(s), some(l)) => { some(hsl(h, s, l)) }
_ { fail_unrecognized(color) } _ => { fail_unrecognized(color) }
} }
} }
@ -155,8 +155,8 @@ mod parsing {
alt (float::from_str(vals[0]), float::from_str(vals[1]), alt (float::from_str(vals[0]), float::from_str(vals[1]),
float::from_str(vals[2]), float::from_str(vals[3])) { float::from_str(vals[2]), float::from_str(vals[3])) {
(some(h), some(s), some(l), some(a)) { some(hsla(h, s, l, a)) } (some(h), some(s), some(l), some(a)) => { some(hsla(h, s, l, a)) }
_ { fail_unrecognized(color) } _ => { fail_unrecognized(color) }
} }
} }
@ -165,11 +165,11 @@ mod parsing {
// TODO: extend this // TODO: extend this
fn parse_color(color : ~str) -> option<Color> { fn parse_color(color : ~str) -> option<Color> {
alt color { alt color {
c if c.starts_with(~"rgb(") { parse_rgb(c) } c if c.starts_with(~"rgb(") => parse_rgb(c),
c if c.starts_with(~"rgba(") { parse_rgba(c) } c if c.starts_with(~"rgba(") => parse_rgba(c),
c if c.starts_with(~"hsl(") { parse_hsl(c) } c if c.starts_with(~"hsl(") => parse_hsl(c),
c if c.starts_with(~"hsla(") { parse_hsla(c) } c if c.starts_with(~"hsla(") => parse_hsla(c),
c { parse_by_name(c) } c => parse_by_name(c)
} }
} }
} }

View file

@ -22,8 +22,8 @@ fn each_child<T:copy,O:ReadMethods<T>>(ops: O, node: T, f: fn(T) -> bool) {
let mut p = ops.with_tree_fields(node, |f| f.first_child); let mut p = ops.with_tree_fields(node, |f| f.first_child);
loop { loop {
alt copy p { alt copy p {
none { return; } none => { return; }
some(c) { some(c) => {
if !f(c) { return; } if !f(c) { return; }
p = ops.with_tree_fields(c, |f| f.next_sibling); p = ops.with_tree_fields(c, |f| f.next_sibling);
} }
@ -43,8 +43,8 @@ fn add_child<T:copy,O:WriteMethods<T>>(ops: O, parent: T, child: T) {
ops.with_tree_fields(child, |child_tf| { ops.with_tree_fields(child, |child_tf| {
alt child_tf.parent { alt child_tf.parent {
some(_) { fail ~"Already has a parent"; } some(_) => { fail ~"Already has a parent"; }
none { child_tf.parent = some(parent); } none => { child_tf.parent = some(parent); }
} }
assert child_tf.prev_sibling == none; assert child_tf.prev_sibling == none;
@ -52,10 +52,10 @@ fn add_child<T:copy,O:WriteMethods<T>>(ops: O, parent: T, child: T) {
ops.with_tree_fields(parent, |parent_tf| { ops.with_tree_fields(parent, |parent_tf| {
alt copy parent_tf.last_child { alt copy parent_tf.last_child {
none { none => {
parent_tf.first_child = some(child); parent_tf.first_child = some(child);
} }
some(lc) { some(lc) => {
let lc = lc; // satisfy alias checker let lc = lc; // satisfy alias checker
ops.with_tree_fields(lc, |lc_tf| { ops.with_tree_fields(lc, |lc_tf| {
assert lc_tf.next_sibling == none; assert lc_tf.next_sibling == none;

View file

@ -12,6 +12,7 @@ Create a URL object from a string. Does various helpful browsery things like
is based off the current url is based off the current url
*/ */
#[allow(non_implicitly_copyable_typarams)]
fn make_url(str_url: ~str, current_url: option<url>) -> url { fn make_url(str_url: ~str, current_url: option<url>) -> url {
let mut schm = get_scheme(str_url); let mut schm = get_scheme(str_url);
let str_url = if result::is_err(schm) { let str_url = if result::is_err(schm) {
@ -27,13 +28,13 @@ fn make_url(str_url: ~str, current_url: option<url>) -> url {
} else { } else {
let path = path::split(current_url.path); let path = path::split(current_url.path);
let path = path.init(); let path = path.init();
let path = path::connect_many(path + ~[str_url]); let path = path::connect_many(path + ~[copy str_url]);
current_url.scheme + "://" + path::connect(current_url.host, path) current_url.scheme + "://" + path::connect(current_url.host, path)
} }
} }
} else { } else {
str_url copy str_url
}; };
// FIXME: Need to handle errors // FIXME: Need to handle errors