diff --git a/src/servo/content.rs b/src/servo/content.rs index 673db24e9cc..9d1bd0d3284 100644 --- a/src/servo/content.rs +++ b/src/servo/content.rs @@ -88,7 +88,8 @@ struct Content { let resource_task: ResourceTask; - new(layout: Layout, sink: S, from_master: Port, resource_task: ResourceTask) { + new(layout: Layout, sink: S, from_master: Port, + resource_task: ResourceTask) { self.layout = layout; self.sink = sink; self.from_master = from_master; @@ -193,7 +194,7 @@ struct Content { // Send new document and relevant styles to layout // FIXME: Put CSS rules in an arc or something. - self.layout.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url)); + self.layout.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url, self.event_port.chan())); // Indicate that reader was forked so any further // changes will be isolated. @@ -215,6 +216,19 @@ struct Content { } return true; } + ReflowEvent => { + #debug("content got reflow event"); + match copy self.document { + none => { + // Nothing to do. + } + some(document) => { + assert self.doc_url.is_some(); + self.relayout(*document, &self.doc_url.get()); + } + } + return true; + } } } } diff --git a/src/servo/dom/event.rs b/src/servo/dom/event.rs index 2b9dcabe038..aeb49cb0508 100644 --- a/src/servo/dom/event.rs +++ b/src/servo/dom/event.rs @@ -1,4 +1,5 @@ enum Event { - ResizeEvent(int, int) + ResizeEvent(int, int), + ReflowEvent } diff --git a/src/servo/layout/base.rs b/src/servo/layout/base.rs index 495bdc48c42..d6bd9e2dc6f 100644 --- a/src/servo/layout/base.rs +++ b/src/servo/layout/base.rs @@ -21,6 +21,7 @@ import resource::image_cache_task; import image_cache_task::ImageCacheTask; import core::to_str::ToStr; import std::arc::{arc, clone}; +import task::spawn; enum BoxKind { BlockBox, @@ -87,11 +88,13 @@ struct ImageHolder { let mut url : option; let mut image : option>; let image_cache_task: ImageCacheTask; + let reflow: fn~(); - new(-url : url, image_cache_task: ImageCacheTask) { + new(-url : url, image_cache_task: ImageCacheTask, reflow: fn~()) { self.url = some(copy url); self.image = none; self.image_cache_task = image_cache_task; + self.reflow = copy reflow; // Tell the image cache we're going to be interested in this url // FIXME: These two messages must be sent to prep an image for use @@ -117,8 +120,22 @@ struct ImageHolder { self.image_cache_task.send(image_cache_task::GetImage(copy url, response_port.chan())); self.image = match response_port.recv() { image_cache_task::ImageReady(image) => some(clone(&image)), - image_cache_task::ImageNotReady - | image_cache_task::ImageFailed => { + image_cache_task::ImageNotReady => { + // Need to reflow when the image is available + let image_cache_task = self.image_cache_task; + let reflow = copy self.reflow; + do spawn |copy url, move reflow| { + let response_port = port(); + image_cache_task.send(image_cache_task::WaitForImage(copy url, response_port.chan())); + match response_port.recv() { + image_cache_task::ImageReady(*) => reflow(), + image_cache_task::ImageNotReady => fail /*not possible*/, + image_cache_task::ImageFailed => () + } + } + none + } + image_cache_task::ImageFailed => { #info("image was not ready for %s", url.to_str()); // FIXME: Need to schedule another layout when the image is ready none diff --git a/src/servo/layout/layout_task.rs b/src/servo/layout/layout_task.rs index f7199cf43b2..6f0354cb398 100644 --- a/src/servo/layout/layout_task.rs +++ b/src/servo/layout/layout_task.rs @@ -12,6 +12,7 @@ import gfx::renderer::Renderer; import resource::image_cache_task::ImageCacheTask; import std::net::url::url; import style::apply::apply_style; +import dom::event::{Event, ReflowEvent}; import task::*; import comm::*; @@ -19,7 +20,7 @@ import comm::*; type Layout = Chan; enum Msg { - BuildMsg(Node, arc, url), + BuildMsg(Node, arc, url, Chan), PingMsg(Chan), ExitMsg } @@ -33,7 +34,7 @@ fn Layout(renderer: Renderer, image_cache_task: ImageCacheTask) -> Layout { #debug("layout: ExitMsg received"); break; } - BuildMsg(node, styles, doc_url) => { + BuildMsg(node, styles, doc_url, event_chan) => { #debug("layout: received layout request for:"); node.dump(); @@ -44,7 +45,9 @@ fn Layout(renderer: Renderer, image_cache_task: ImageCacheTask) -> Layout { let this_box = node.construct_boxes(); this_box.dump(); - apply_style(this_box, &doc_url, image_cache_task); + let reflow: fn~() = || event_chan.send(ReflowEvent); + + apply_style(this_box, &doc_url, image_cache_task, reflow); this_box.reflow_subtree(px_to_au(800)); diff --git a/src/servo/layout/style/apply.rs b/src/servo/layout/style/apply.rs index 28ff3211639..575cbf145f5 100644 --- a/src/servo/layout/style/apply.rs +++ b/src/servo/layout/style/apply.rs @@ -14,13 +14,15 @@ struct StyleApplicator { box: @Box; doc_url: &url; image_cache_task: ImageCacheTask; + reflow: fn~(); } -fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask) { +fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask, reflow: fn~()) { let applicator = StyleApplicator { box: box, doc_url: doc_url, - image_cache_task: image_cache_task + image_cache_task: image_cache_task, + reflow: reflow }; applicator.apply_css_style(); @@ -28,11 +30,12 @@ fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask) { #[doc="A wrapper around a set of functions that can be applied as a top-down traversal of layout boxes."] -fn inheritance_wrapper(box : @Box, doc_url: &url, image_cache_task: ImageCacheTask) { +fn inheritance_wrapper(box : @Box, doc_url: &url, image_cache_task: ImageCacheTask, reflow: fn~()) { let applicator = StyleApplicator { box: box, doc_url: doc_url, - image_cache_task: image_cache_task + image_cache_task: image_cache_task, + reflow: reflow }; applicator.apply_style(); inhereit_height(box); @@ -103,8 +106,9 @@ impl StyleApplicator { fn apply_css_style() { let doc_url = copy *self.doc_url; let image_cache_task = self.image_cache_task; + let reflow = copy self.reflow; do top_down_traversal(self.box) |box, move doc_url| { - inheritance_wrapper(box, &doc_url, image_cache_task); + inheritance_wrapper(box, &doc_url, image_cache_task, reflow); } } @@ -136,7 +140,7 @@ impl StyleApplicator { // FIXME: Some sort of BASE HREF support! // FIXME: Parse URLs! let new_url = make_url(option::unwrap(url), some(copy *self.doc_url)); - self.box.appearance.background_image = some(ImageHolder(new_url, self.image_cache_task)) + self.box.appearance.background_image = some(ImageHolder(new_url, self.image_cache_task, self.reflow)) }; } _ => { /* Ignore. */ } diff --git a/src/servo/resource/image_cache_task.rs b/src/servo/resource/image_cache_task.rs index 7e390398e3e..0943268996e 100644 --- a/src/servo/resource/image_cache_task.rs +++ b/src/servo/resource/image_cache_task.rs @@ -1,4 +1,4 @@ -export Msg, Prefetch, Decode, GetImage, Exit; +export Msg, Prefetch, Decode, GetImage, WaitForImage, Exit; export ImageResponseMsg, ImageReady, ImageNotReady, ImageFailed; export ImageCacheTask; export image_cache_task;