mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
auto merge of #647 : tkuehn/servo/master, r=metajack
This will be necessary for the constellation to properly assign sizes to iframes when a parent layout performs reflow.
This commit is contained in:
commit
feee4ddcb2
6 changed files with 144 additions and 106 deletions
|
@ -43,12 +43,25 @@ pub struct Constellation {
|
|||
}
|
||||
|
||||
/// Stores the Id of the outermost frame's pipeline, along with a vector of children frames
|
||||
#[deriving(Clone)]
|
||||
struct FrameTree {
|
||||
pipeline: @mut Pipeline,
|
||||
parent: Option<@mut Pipeline>,
|
||||
children: ~[@mut FrameTree],
|
||||
}
|
||||
// Need to clone the FrameTrees, but _not_ the Pipelines
|
||||
impl Clone for FrameTree {
|
||||
fn clone(&self) -> FrameTree {
|
||||
let mut children = ~[];
|
||||
for self.children.iter().advance |&frame_tree| {
|
||||
children.push(@mut (*frame_tree).clone());
|
||||
}
|
||||
FrameTree {
|
||||
pipeline: self.pipeline,
|
||||
parent: self.parent.clone(),
|
||||
children: children,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SendableFrameTree {
|
||||
pipeline: Pipeline,
|
||||
|
@ -75,7 +88,7 @@ impl FrameTree {
|
|||
/// Returns the frame tree whose key is id
|
||||
fn find_mut(@mut self, id: PipelineId) -> Option<@mut FrameTree> {
|
||||
if self.pipeline.id == id { return Some(self); }
|
||||
for self.children.mut_iter().advance |frame_tree| {
|
||||
for self.children.iter().advance |frame_tree| {
|
||||
let found = frame_tree.find_mut(id);
|
||||
if found.is_some() { return found; }
|
||||
}
|
||||
|
@ -188,32 +201,28 @@ impl NavigationContext {
|
|||
evicted
|
||||
}
|
||||
|
||||
/// Returns the frame tree whose key is pipeline_id.
|
||||
pub fn find(&mut self, pipeline_id: PipelineId) -> Option<@mut FrameTree> {
|
||||
for self.current.mut_iter().advance |frame_tree| {
|
||||
let found = frame_tree.find_mut(pipeline_id);
|
||||
if found.is_some() { return found; }
|
||||
}
|
||||
let mut forward = self.next.mut_rev_iter();
|
||||
let mut backward = self.previous.mut_rev_iter();
|
||||
loop {
|
||||
match (forward.next(), backward.next()) {
|
||||
(None, None) => {
|
||||
return None;
|
||||
}
|
||||
(next_forward, next_backward) => {
|
||||
let mut next_forward = next_forward;
|
||||
let mut next_backward = next_backward;
|
||||
for next_forward.mut_iter().advance |frame_tree| {
|
||||
let found = frame_tree.find_mut(pipeline_id);
|
||||
if found.is_some() { return found; }
|
||||
}
|
||||
for next_backward.mut_iter().advance |frame_tree| {
|
||||
let found = frame_tree.find_mut(pipeline_id);
|
||||
if found.is_some() { return found; }
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Returns the frame trees whose keys are pipeline_id.
|
||||
pub fn find_all(&mut self, pipeline_id: PipelineId) -> ~[@mut FrameTree] {
|
||||
let from_current = do self.current.iter().filter_map |frame_tree| {
|
||||
frame_tree.find_mut(pipeline_id)
|
||||
};
|
||||
let from_next = do self.next.iter().filter_map |frame_tree| {
|
||||
frame_tree.find_mut(pipeline_id)
|
||||
};
|
||||
let from_prev = do self.previous.iter().filter_map |frame_tree| {
|
||||
frame_tree.find_mut(pipeline_id)
|
||||
};
|
||||
from_prev.chain_(from_current).chain_(from_next).collect()
|
||||
}
|
||||
|
||||
pub fn contains(&mut self, pipeline_id: PipelineId) -> bool {
|
||||
let from_current = self.current.iter();
|
||||
let from_next = self.next.iter();
|
||||
let from_prev = self.previous.iter();
|
||||
|
||||
let mut all_contained = from_prev.chain_(from_current).chain_(from_next);
|
||||
do all_contained.any |frame_tree| {
|
||||
frame_tree.contains(pipeline_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +278,7 @@ impl Constellation {
|
|||
/// Helper function for getting a unique pipeline Id
|
||||
fn get_next_pipeline_id(&mut self) -> PipelineId {
|
||||
let id = self.next_pipeline_id;
|
||||
self.next_pipeline_id = PipelineId(*id + 1);
|
||||
*self.next_pipeline_id += 1;
|
||||
id
|
||||
}
|
||||
|
||||
|
@ -297,16 +306,17 @@ impl Constellation {
|
|||
// This should only be called once per constellation, and only by the browser
|
||||
InitLoadUrlMsg(url) => {
|
||||
let pipeline = @mut Pipeline::create(self.get_next_pipeline_id(),
|
||||
self.chan.clone(),
|
||||
self.compositor_chan.clone(),
|
||||
self.image_cache_task.clone(),
|
||||
self.resource_task.clone(),
|
||||
self.profiler_chan.clone(),
|
||||
copy self.opts,
|
||||
{
|
||||
let size = self.compositor_chan.get_size();
|
||||
from_value(Size2D(size.width as uint, size.height as uint))
|
||||
});
|
||||
None,
|
||||
self.chan.clone(),
|
||||
self.compositor_chan.clone(),
|
||||
self.image_cache_task.clone(),
|
||||
self.resource_task.clone(),
|
||||
self.profiler_chan.clone(),
|
||||
copy self.opts,
|
||||
{
|
||||
let size = self.compositor_chan.get_size();
|
||||
from_value(Size2D(size.width as uint, size.height as uint))
|
||||
});
|
||||
if url.path.ends_with(".js") {
|
||||
pipeline.script_chan.send(ExecuteMsg(pipeline.id, url));
|
||||
} else {
|
||||
|
@ -324,35 +334,30 @@ impl Constellation {
|
|||
self.pipelines.insert(pipeline.id, pipeline);
|
||||
}
|
||||
|
||||
LoadIframeUrlMsg(url, source_pipeline_id, size_future) => {
|
||||
LoadIframeUrlMsg(url, source_pipeline_id, subpage_id, size_future) => {
|
||||
// A message from the script associated with pipeline_id that it has
|
||||
// parsed an iframe during html parsing. This iframe will result in a
|
||||
// new pipeline being spawned and a frame tree being added to pipeline_id's
|
||||
// frame tree's children. This message is never the result of a link clicked
|
||||
// or a new url entered.
|
||||
// Start by finding the frame tree matching the pipeline id,
|
||||
// and add the new pipeline to its sub frames. The frame tree
|
||||
// could already be in the navigation context, or it could still
|
||||
// be loading, in which case it is a new id in a constellation.pending_frames
|
||||
// frame change, because pages aren't added to the navi context until they finish
|
||||
// loading (excluding iframes). Which is checked first is seemingly arbitrary
|
||||
let next_pipeline_id = self.get_next_pipeline_id();
|
||||
let frame_tree = {
|
||||
let frame_tree = self.navigation_context.find(source_pipeline_id);
|
||||
match frame_tree {
|
||||
Some(frame_tree) => frame_tree,
|
||||
None => {
|
||||
let frame_change = do self.pending_frames.mut_iter().find_ |frame_change| {
|
||||
frame_change.after.pipeline.id == source_pipeline_id
|
||||
};
|
||||
let frame_change = frame_change.expect("Constellation: source pipeline id
|
||||
of LoadIframeUrlMsg is not in navigation context nor a pending painter.
|
||||
This should be impossible.");
|
||||
frame_change.after
|
||||
}
|
||||
}
|
||||
// Start by finding the frame trees matching the pipeline id,
|
||||
// and add the new pipeline to their sub frames.
|
||||
let frame_trees: ~[@mut FrameTree] = {
|
||||
let matching_navi_frames = self.navigation_context.find_all(source_pipeline_id);
|
||||
let matching_pending_frames = do self.pending_frames.iter().filter_map |frame_change| {
|
||||
frame_change.after.find_mut(source_pipeline_id)
|
||||
};
|
||||
matching_navi_frames.iter().transform(|&x| x).chain_(matching_pending_frames).collect()
|
||||
};
|
||||
|
||||
if frame_trees.is_empty() {
|
||||
fail!("Constellation: source pipeline id of LoadIframeUrlMsg is not in
|
||||
navigation context, nor is it in a pending frame. This should be
|
||||
impossible.");
|
||||
}
|
||||
|
||||
let next_pipeline_id = self.get_next_pipeline_id();
|
||||
|
||||
// Compare the pipeline's url to the new url. If the origin is the same,
|
||||
// then reuse the script task in creating the new pipeline
|
||||
let source_pipeline = *self.pipelines.find(&source_pipeline_id).expect("Constellation:
|
||||
|
@ -368,6 +373,7 @@ impl Constellation {
|
|||
source_url.port == url.port) {
|
||||
// Reuse the script task if same-origin url's
|
||||
Pipeline::with_script(next_pipeline_id,
|
||||
Some(subpage_id),
|
||||
self.chan.clone(),
|
||||
self.compositor_chan.clone(),
|
||||
self.image_cache_task.clone(),
|
||||
|
@ -378,6 +384,7 @@ impl Constellation {
|
|||
} else {
|
||||
// Create a new script task if not same-origin url's
|
||||
Pipeline::create(next_pipeline_id,
|
||||
Some(subpage_id),
|
||||
self.chan.clone(),
|
||||
self.compositor_chan.clone(),
|
||||
self.image_cache_task.clone(),
|
||||
|
@ -392,11 +399,13 @@ impl Constellation {
|
|||
} else {
|
||||
pipeline.load(url, None);
|
||||
}
|
||||
frame_tree.children.push(@mut FrameTree {
|
||||
pipeline: pipeline,
|
||||
parent: Some(source_pipeline),
|
||||
children: ~[],
|
||||
});
|
||||
for frame_trees.iter().advance |frame_tree| {
|
||||
frame_tree.children.push(@mut FrameTree {
|
||||
pipeline: pipeline,
|
||||
parent: Some(source_pipeline),
|
||||
children: ~[],
|
||||
});
|
||||
}
|
||||
self.pipelines.insert(pipeline.id, pipeline);
|
||||
}
|
||||
|
||||
|
@ -406,6 +415,11 @@ impl Constellation {
|
|||
LoadUrlMsg(source_id, url, size_future) => {
|
||||
debug!("received message to load %s", url::to_str(&url));
|
||||
// Make sure no pending page would be overridden.
|
||||
let source_frame = self.current_frame().get_ref().find_mut(source_id).expect(
|
||||
"Constellation: received a LoadUrlMsg from a pipeline_id associated
|
||||
with a pipeline not in the active frame tree. This should be
|
||||
impossible.");
|
||||
|
||||
for self.pending_frames.iter().advance |frame_change| {
|
||||
let old_id = frame_change.before.expect("Constellation: Received load msg
|
||||
from pipeline, but there is no currently active page. This should
|
||||
|
@ -413,7 +427,7 @@ impl Constellation {
|
|||
let changing_frame = self.current_frame().get_ref().find_mut(old_id).expect("Constellation:
|
||||
Pending change has non-active source pipeline. This should be
|
||||
impossible.");
|
||||
if changing_frame.contains(source_id) {
|
||||
if changing_frame.contains(source_id) || source_frame.contains(old_id) {
|
||||
// id that sent load msg is being changed already; abort
|
||||
return true;
|
||||
}
|
||||
|
@ -421,33 +435,25 @@ impl Constellation {
|
|||
// Being here means either there are no pending frames, or none of the pending
|
||||
// changes would be overriden by changing the subframe associated with source_id.
|
||||
|
||||
let parent = source_frame.parent.clone();
|
||||
let subpage_id = source_frame.pipeline.subpage_id.clone();
|
||||
let next_pipeline_id = self.get_next_pipeline_id();
|
||||
|
||||
let pipeline = @mut Pipeline::create(next_pipeline_id,
|
||||
self.chan.clone(),
|
||||
self.compositor_chan.clone(),
|
||||
self.image_cache_task.clone(),
|
||||
self.resource_task.clone(),
|
||||
self.profiler_chan.clone(),
|
||||
copy self.opts,
|
||||
size_future);
|
||||
subpage_id,
|
||||
self.chan.clone(),
|
||||
self.compositor_chan.clone(),
|
||||
self.image_cache_task.clone(),
|
||||
self.resource_task.clone(),
|
||||
self.profiler_chan.clone(),
|
||||
copy self.opts,
|
||||
size_future);
|
||||
|
||||
if url.path.ends_with(".js") {
|
||||
pipeline.script_chan.send(ExecuteMsg(pipeline.id, url));
|
||||
} else {
|
||||
pipeline.load(url, Some(constellation_msg::Load));
|
||||
|
||||
let parent = if self.current_frame().get_ref().pipeline.id == source_id {
|
||||
// source_id is the root of the current frame tree; replace whole tree
|
||||
None
|
||||
} else {
|
||||
// id is not the root of the current frame tree, but is in the frame tree;
|
||||
// replace only the subtree
|
||||
let source_frame = self.current_frame().get_ref().find_mut(source_id).expect(
|
||||
"Constellation: received a LoadUrlMsg from a pipeline_id associated
|
||||
with a pipeline not in the active frame tree. This should be
|
||||
impossible.");
|
||||
source_frame.parent
|
||||
};
|
||||
self.pending_frames.push(FrameChange{
|
||||
before: Some(source_id),
|
||||
after: @mut FrameTree {
|
||||
|
@ -532,7 +538,7 @@ impl Constellation {
|
|||
// Create the next frame tree that will be given to the compositor
|
||||
let next_frame_tree = match to_add.parent {
|
||||
None => to_add, // to_add is the root
|
||||
Some(_parent) => self.current_frame().get(),
|
||||
Some(_parent) => @mut (*self.current_frame().get()).clone(),
|
||||
};
|
||||
|
||||
// If there are frames to revoke permission from, do so now.
|
||||
|
@ -613,7 +619,7 @@ impl Constellation {
|
|||
for evicted.iter().advance |frame_tree| {
|
||||
// exit any pipelines that don't exist outside the evicted frame trees
|
||||
for frame_tree.iter().advance |frame| {
|
||||
if self.navigation_context.find(frame.pipeline.id).is_none() {
|
||||
if !self.navigation_context.contains(frame.pipeline.id) {
|
||||
frame_tree.pipeline.exit();
|
||||
self.pipelines.remove(&frame_tree.pipeline.id);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use gfx::opts::Opts;
|
|||
use layout::layout_task::LayoutTask;
|
||||
use script::layout_interface::LayoutChan;
|
||||
use script::script_task::{ExecuteMsg, LoadMsg};
|
||||
use servo_msg::constellation_msg::{ConstellationChan, NavigationType, PipelineId};
|
||||
use servo_msg::constellation_msg::{ConstellationChan, NavigationType, PipelineId, SubpageId};
|
||||
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
|
||||
use script::script_task;
|
||||
use servo_net::image_cache_task::ImageCacheTask;
|
||||
|
@ -25,6 +25,7 @@ use std::comm;
|
|||
#[deriving(Clone)]
|
||||
pub struct Pipeline {
|
||||
id: PipelineId,
|
||||
subpage_id: Option<SubpageId>,
|
||||
script_chan: ScriptChan,
|
||||
layout_chan: LayoutChan,
|
||||
render_chan: RenderChan,
|
||||
|
@ -36,13 +37,14 @@ pub struct Pipeline {
|
|||
impl Pipeline {
|
||||
/// Starts a render task, layout task, and script task. Returns the channels wrapped in a struct.
|
||||
pub fn with_script(id: PipelineId,
|
||||
constellation_chan: ConstellationChan,
|
||||
compositor_chan: CompositorChan,
|
||||
image_cache_task: ImageCacheTask,
|
||||
profiler_chan: ProfilerChan,
|
||||
opts: Opts,
|
||||
script_pipeline: &Pipeline,
|
||||
size_future: Future<Size2D<uint>>) -> Pipeline {
|
||||
subpage_id: Option<SubpageId>,
|
||||
constellation_chan: ConstellationChan,
|
||||
compositor_chan: CompositorChan,
|
||||
image_cache_task: ImageCacheTask,
|
||||
profiler_chan: ProfilerChan,
|
||||
opts: Opts,
|
||||
script_pipeline: &Pipeline,
|
||||
size_future: Future<Size2D<uint>>) -> Pipeline {
|
||||
|
||||
let (layout_port, layout_chan) = special_stream!(LayoutChan);
|
||||
let (render_port, render_chan) = special_stream!(RenderChan);
|
||||
|
@ -72,6 +74,7 @@ impl Pipeline {
|
|||
script_pipeline.script_chan.send(AttachLayoutMsg(new_layout_info));
|
||||
|
||||
Pipeline::new(id,
|
||||
subpage_id,
|
||||
script_pipeline.script_chan.clone(),
|
||||
layout_chan,
|
||||
render_chan)
|
||||
|
@ -79,6 +82,7 @@ impl Pipeline {
|
|||
}
|
||||
|
||||
pub fn create(id: PipelineId,
|
||||
subpage_id: Option<SubpageId>,
|
||||
constellation_chan: ConstellationChan,
|
||||
compositor_chan: CompositorChan,
|
||||
image_cache_task: ImageCacheTask,
|
||||
|
@ -117,18 +121,21 @@ impl Pipeline {
|
|||
copy opts,
|
||||
profiler_chan);
|
||||
Pipeline::new(id,
|
||||
subpage_id,
|
||||
script_chan,
|
||||
layout_chan,
|
||||
render_chan)
|
||||
}
|
||||
|
||||
pub fn new(id: PipelineId,
|
||||
subpage_id: Option<SubpageId>,
|
||||
script_chan: ScriptChan,
|
||||
layout_chan: LayoutChan,
|
||||
render_chan: RenderChan)
|
||||
-> Pipeline {
|
||||
Pipeline {
|
||||
id: id,
|
||||
subpage_id: subpage_id,
|
||||
script_chan: script_chan,
|
||||
layout_chan: layout_chan,
|
||||
render_chan: render_chan,
|
||||
|
|
|
@ -30,7 +30,7 @@ pub enum Msg {
|
|||
ExitMsg(Chan<()>),
|
||||
InitLoadUrlMsg(Url),
|
||||
LoadUrlMsg(PipelineId, Url, Future<Size2D<uint>>),
|
||||
LoadIframeUrlMsg(Url, PipelineId, Future<Size2D<uint>>),
|
||||
LoadIframeUrlMsg(Url, PipelineId, SubpageId, Future<Size2D<uint>>),
|
||||
NavigateMsg(NavigationDirection),
|
||||
RendererReadyMsg(PipelineId),
|
||||
ResizedWindowBroadcast(Size2D<uint>),
|
||||
|
@ -51,3 +51,5 @@ pub enum NavigationDirection {
|
|||
|
||||
#[deriving(Clone, Eq, IterBytes)]
|
||||
pub struct PipelineId(uint);
|
||||
#[deriving(Clone, Eq, IterBytes)]
|
||||
pub struct SubpageId(uint);
|
||||
|
|
|
@ -18,6 +18,8 @@ use std::str::eq_slice;
|
|||
use extra::net::url::Url;
|
||||
use geom::size::Size2D;
|
||||
|
||||
use servo_msg::constellation_msg::SubpageId;
|
||||
|
||||
pub struct Element {
|
||||
parent: Node<ScriptView>,
|
||||
tag_name: ~str, // TODO: This should be an atom, not a ~str.
|
||||
|
@ -112,6 +114,7 @@ pub struct HTMLHeadingElement {
|
|||
pub struct HTMLIframeElement {
|
||||
parent: Element,
|
||||
frame: Option<Url>,
|
||||
subpage_id: Option<SubpageId>,
|
||||
size_future_chan: Option<ChanOne<Size2D<uint>>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ use std::str::eq_slice;
|
|||
use std::result;
|
||||
use std::task;
|
||||
use hubbub::hubbub;
|
||||
use servo_msg::constellation_msg::SubpageId;
|
||||
use servo_net::image_cache_task::ImageCacheTask;
|
||||
use servo_net::image_cache_task;
|
||||
use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
|
||||
|
@ -83,7 +84,7 @@ enum JSMessage {
|
|||
pub struct HtmlParserResult {
|
||||
root: AbstractNode<ScriptView>,
|
||||
style_port: Port<Stylesheet>,
|
||||
iframe_port: Port<(Url, Future<Size2D<uint>>)>,
|
||||
iframe_port: Port<(Url, SubpageId, Future<Size2D<uint>>)>,
|
||||
js_port: Port<JSResult>,
|
||||
}
|
||||
|
||||
|
@ -222,7 +223,7 @@ fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptView>
|
|||
handle_element!(cx, tag, "ul", HTMLUListElementTypeId, HTMLUListElement, []);
|
||||
|
||||
handle_element!(cx, tag, "img", HTMLImageElementTypeId, HTMLImageElement, [(image: None)]);
|
||||
handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIframeElement, [(frame: None), (size_future_chan: None)]);
|
||||
handle_element!(cx, tag, "iframe", HTMLIframeElementTypeId, HTMLIframeElement, [(frame: None), (size_future_chan: None), (subpage_id: None)]);
|
||||
|
||||
handle_element!(cx, tag, "h1", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading1)]);
|
||||
handle_element!(cx, tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]);
|
||||
|
@ -240,7 +241,8 @@ fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptView>
|
|||
pub fn parse_html(cx: *JSContext,
|
||||
url: Url,
|
||||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask) -> HtmlParserResult {
|
||||
image_cache_task: ImageCacheTask,
|
||||
next_subpage_id: SubpageId) -> HtmlParserResult {
|
||||
debug!("Hubbub: parsing %?", url);
|
||||
// Spawn a CSS parser to receive links to CSS style sheets.
|
||||
let resource_task2 = resource_task.clone();
|
||||
|
@ -281,6 +283,8 @@ pub fn parse_html(cx: *JSContext,
|
|||
|
||||
let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone());
|
||||
let (iframe_port, iframe_chan) = comm::stream();
|
||||
let next_subpage_id = Cell::new(next_subpage_id);
|
||||
|
||||
parser.set_tree_handler(~hubbub::TreeHandler {
|
||||
create_comment: |data: ~str| {
|
||||
debug!("create comment");
|
||||
|
@ -337,10 +341,18 @@ pub fn parse_html(cx: *JSContext,
|
|||
for src_opt.iter().advance |src| {
|
||||
let iframe_url = make_url(src.clone(), Some(url2.clone()));
|
||||
iframe_element.frame = Some(iframe_url.clone());
|
||||
|
||||
// Size future
|
||||
let (port, chan) = comm::oneshot();
|
||||
iframe_element.size_future_chan = Some(chan);
|
||||
let size_future = from_port(port);
|
||||
iframe_chan.send((iframe_url, size_future));
|
||||
|
||||
// Subpage Id
|
||||
let subpage_id = next_subpage_id.take();
|
||||
iframe_element.subpage_id = Some(subpage_id);
|
||||
next_subpage_id.put_back(SubpageId(*subpage_id + 1));
|
||||
|
||||
iframe_chan.send((iframe_url, subpage_id, size_future));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use layout_interface::{ReflowDocumentDamage, ReflowForDisplay, ReflowGoal};
|
|||
use layout_interface::ReflowMsg;
|
||||
use layout_interface;
|
||||
use servo_msg::constellation_msg::{ConstellationChan, LoadUrlMsg, NavigationDirection};
|
||||
use servo_msg::constellation_msg::{PipelineId, RendererReadyMsg, ResizedWindowBroadcast};
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId, RendererReadyMsg, ResizedWindowBroadcast};
|
||||
use servo_msg::constellation_msg::{LoadIframeUrlMsg};
|
||||
use servo_msg::constellation_msg;
|
||||
|
||||
|
@ -128,6 +128,8 @@ pub struct Page {
|
|||
/// and simply caches pages forever (!). The bool indicates if reflow is required
|
||||
/// when reloading.
|
||||
url: Option<(Url, bool)>,
|
||||
|
||||
next_subpage_id: SubpageId,
|
||||
}
|
||||
|
||||
pub struct PageTree {
|
||||
|
@ -151,6 +153,7 @@ impl PageTree {
|
|||
window_size: size_future,
|
||||
js_info: None,
|
||||
url: None,
|
||||
next_subpage_id: SubpageId(0),
|
||||
},
|
||||
inner: ~[],
|
||||
}
|
||||
|
@ -599,7 +602,8 @@ impl ScriptTask {
|
|||
let html_parsing_result = hubbub_html_parser::parse_html(page.js_info.get_ref().js_compartment.cx.ptr,
|
||||
url.clone(),
|
||||
self.resource_task.clone(),
|
||||
self.image_cache_task.clone());
|
||||
self.image_cache_task.clone(),
|
||||
page.next_subpage_id.clone());
|
||||
|
||||
let HtmlParserResult {root, js_port, style_port, iframe_port} = html_parsing_result;
|
||||
|
||||
|
@ -624,12 +628,14 @@ impl ScriptTask {
|
|||
// FIXME: These should be streamed to layout as they're parsed. We don't need to stop here
|
||||
// in the script task.
|
||||
|
||||
let get_iframes = |iframe_port: &Port<(Url, Future<Size2D<uint>>)>| loop {
|
||||
let get_iframes = |iframe_port: &Port<(Url, SubpageId, Future<Size2D<uint>>)>| loop {
|
||||
match iframe_port.try_recv() {
|
||||
None => break,
|
||||
Some((iframe_url, size_future)) => {
|
||||
Some((iframe_url, subpage_id, size_future)) => {
|
||||
page.next_subpage_id = SubpageId(*subpage_id + 1);
|
||||
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
|
||||
pipeline_id,
|
||||
subpage_id,
|
||||
size_future));
|
||||
}
|
||||
}
|
||||
|
@ -652,9 +658,11 @@ impl ScriptTask {
|
|||
Left(Some(sheet)) => {
|
||||
page.layout_chan.send(AddStylesheetMsg(sheet));
|
||||
}
|
||||
Right(Some((iframe_url, size_future))) => {
|
||||
Right(Some((iframe_url, subpage_id, size_future))) => {
|
||||
page.next_subpage_id = SubpageId(*subpage_id + 1);
|
||||
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
|
||||
pipeline_id,
|
||||
subpage_id,
|
||||
size_future));
|
||||
}
|
||||
Right(None) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue