added subpage ids to map from iframe to all associated pipelines

This commit is contained in:
Tim Kuehn 2013-07-30 16:13:04 -07:00
parent a2bdab7989
commit 2348fbf46d
6 changed files with 71 additions and 47 deletions

View file

@ -269,7 +269,7 @@ impl Constellation {
/// Helper function for getting a unique pipeline Id /// Helper function for getting a unique pipeline Id
fn get_next_pipeline_id(&mut self) -> PipelineId { fn get_next_pipeline_id(&mut self) -> PipelineId {
let id = self.next_pipeline_id; let id = self.next_pipeline_id;
self.next_pipeline_id = PipelineId(*id + 1); *self.next_pipeline_id += 1;
id id
} }
@ -297,16 +297,17 @@ impl Constellation {
// This should only be called once per constellation, and only by the browser // This should only be called once per constellation, and only by the browser
InitLoadUrlMsg(url) => { InitLoadUrlMsg(url) => {
let pipeline = @mut Pipeline::create(self.get_next_pipeline_id(), let pipeline = @mut Pipeline::create(self.get_next_pipeline_id(),
self.chan.clone(), None,
self.compositor_chan.clone(), self.chan.clone(),
self.image_cache_task.clone(), self.compositor_chan.clone(),
self.resource_task.clone(), self.image_cache_task.clone(),
self.profiler_chan.clone(), self.resource_task.clone(),
copy self.opts, 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)) let size = self.compositor_chan.get_size();
}); from_value(Size2D(size.width as uint, size.height as uint))
});
if url.path.ends_with(".js") { if url.path.ends_with(".js") {
pipeline.script_chan.send(ExecuteMsg(pipeline.id, url)); pipeline.script_chan.send(ExecuteMsg(pipeline.id, url));
} else { } else {
@ -324,7 +325,7 @@ impl Constellation {
self.pipelines.insert(pipeline.id, pipeline); 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 // A message from the script associated with pipeline_id that it has
// parsed an iframe during html parsing. This iframe will result in a // 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 // new pipeline being spawned and a frame tree being added to pipeline_id's
@ -368,6 +369,7 @@ impl Constellation {
source_url.port == url.port) { source_url.port == url.port) {
// Reuse the script task if same-origin url's // Reuse the script task if same-origin url's
Pipeline::with_script(next_pipeline_id, Pipeline::with_script(next_pipeline_id,
Some(subpage_id),
self.chan.clone(), self.chan.clone(),
self.compositor_chan.clone(), self.compositor_chan.clone(),
self.image_cache_task.clone(), self.image_cache_task.clone(),
@ -378,6 +380,7 @@ impl Constellation {
} else { } else {
// Create a new script task if not same-origin url's // Create a new script task if not same-origin url's
Pipeline::create(next_pipeline_id, Pipeline::create(next_pipeline_id,
Some(subpage_id),
self.chan.clone(), self.chan.clone(),
self.compositor_chan.clone(), self.compositor_chan.clone(),
self.image_cache_task.clone(), self.image_cache_task.clone(),
@ -421,33 +424,29 @@ impl Constellation {
// Being here means either there are no pending frames, or none of the pending // 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. // changes would be overriden by changing the subframe associated with source_id.
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.");
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 next_pipeline_id = self.get_next_pipeline_id();
let pipeline = @mut Pipeline::create(next_pipeline_id, let pipeline = @mut Pipeline::create(next_pipeline_id,
self.chan.clone(), subpage_id,
self.compositor_chan.clone(), self.chan.clone(),
self.image_cache_task.clone(), self.compositor_chan.clone(),
self.resource_task.clone(), self.image_cache_task.clone(),
self.profiler_chan.clone(), self.resource_task.clone(),
copy self.opts, self.profiler_chan.clone(),
size_future); copy self.opts,
size_future);
if url.path.ends_with(".js") { if url.path.ends_with(".js") {
pipeline.script_chan.send(ExecuteMsg(pipeline.id, url)); pipeline.script_chan.send(ExecuteMsg(pipeline.id, url));
} else { } else {
pipeline.load(url, Some(constellation_msg::Load)); 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{ self.pending_frames.push(FrameChange{
before: Some(source_id), before: Some(source_id),
after: @mut FrameTree { after: @mut FrameTree {

View file

@ -11,7 +11,7 @@ use gfx::opts::Opts;
use layout::layout_task::LayoutTask; use layout::layout_task::LayoutTask;
use script::layout_interface::LayoutChan; use script::layout_interface::LayoutChan;
use script::script_task::{ExecuteMsg, LoadMsg}; 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::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
use script::script_task; use script::script_task;
use servo_net::image_cache_task::ImageCacheTask; use servo_net::image_cache_task::ImageCacheTask;
@ -25,6 +25,7 @@ use std::comm;
#[deriving(Clone)] #[deriving(Clone)]
pub struct Pipeline { pub struct Pipeline {
id: PipelineId, id: PipelineId,
subpage_id: Option<SubpageId>,
script_chan: ScriptChan, script_chan: ScriptChan,
layout_chan: LayoutChan, layout_chan: LayoutChan,
render_chan: RenderChan, render_chan: RenderChan,
@ -36,13 +37,14 @@ pub struct Pipeline {
impl Pipeline { impl Pipeline {
/// Starts a render task, layout task, and script task. Returns the channels wrapped in a struct. /// Starts a render task, layout task, and script task. Returns the channels wrapped in a struct.
pub fn with_script(id: PipelineId, pub fn with_script(id: PipelineId,
constellation_chan: ConstellationChan, subpage_id: Option<SubpageId>,
compositor_chan: CompositorChan, constellation_chan: ConstellationChan,
image_cache_task: ImageCacheTask, compositor_chan: CompositorChan,
profiler_chan: ProfilerChan, image_cache_task: ImageCacheTask,
opts: Opts, profiler_chan: ProfilerChan,
script_pipeline: &Pipeline, opts: Opts,
size_future: Future<Size2D<uint>>) -> Pipeline { script_pipeline: &Pipeline,
size_future: Future<Size2D<uint>>) -> Pipeline {
let (layout_port, layout_chan) = special_stream!(LayoutChan); let (layout_port, layout_chan) = special_stream!(LayoutChan);
let (render_port, render_chan) = special_stream!(RenderChan); let (render_port, render_chan) = special_stream!(RenderChan);
@ -72,6 +74,7 @@ impl Pipeline {
script_pipeline.script_chan.send(AttachLayoutMsg(new_layout_info)); script_pipeline.script_chan.send(AttachLayoutMsg(new_layout_info));
Pipeline::new(id, Pipeline::new(id,
subpage_id,
script_pipeline.script_chan.clone(), script_pipeline.script_chan.clone(),
layout_chan, layout_chan,
render_chan) render_chan)
@ -79,6 +82,7 @@ impl Pipeline {
} }
pub fn create(id: PipelineId, pub fn create(id: PipelineId,
subpage_id: Option<SubpageId>,
constellation_chan: ConstellationChan, constellation_chan: ConstellationChan,
compositor_chan: CompositorChan, compositor_chan: CompositorChan,
image_cache_task: ImageCacheTask, image_cache_task: ImageCacheTask,
@ -117,18 +121,21 @@ impl Pipeline {
copy opts, copy opts,
profiler_chan); profiler_chan);
Pipeline::new(id, Pipeline::new(id,
subpage_id,
script_chan, script_chan,
layout_chan, layout_chan,
render_chan) render_chan)
} }
pub fn new(id: PipelineId, pub fn new(id: PipelineId,
subpage_id: Option<SubpageId>,
script_chan: ScriptChan, script_chan: ScriptChan,
layout_chan: LayoutChan, layout_chan: LayoutChan,
render_chan: RenderChan) render_chan: RenderChan)
-> Pipeline { -> Pipeline {
Pipeline { Pipeline {
id: id, id: id,
subpage_id: subpage_id,
script_chan: script_chan, script_chan: script_chan,
layout_chan: layout_chan, layout_chan: layout_chan,
render_chan: render_chan, render_chan: render_chan,

View file

@ -30,7 +30,7 @@ pub enum Msg {
ExitMsg(Chan<()>), ExitMsg(Chan<()>),
InitLoadUrlMsg(Url), InitLoadUrlMsg(Url),
LoadUrlMsg(PipelineId, Url, Future<Size2D<uint>>), LoadUrlMsg(PipelineId, Url, Future<Size2D<uint>>),
LoadIframeUrlMsg(Url, PipelineId, Future<Size2D<uint>>), LoadIframeUrlMsg(Url, PipelineId, SubpageId, Future<Size2D<uint>>),
NavigateMsg(NavigationDirection), NavigateMsg(NavigationDirection),
RendererReadyMsg(PipelineId), RendererReadyMsg(PipelineId),
ResizedWindowBroadcast(Size2D<uint>), ResizedWindowBroadcast(Size2D<uint>),
@ -51,3 +51,5 @@ pub enum NavigationDirection {
#[deriving(Clone, Eq, IterBytes)] #[deriving(Clone, Eq, IterBytes)]
pub struct PipelineId(uint); pub struct PipelineId(uint);
#[deriving(Clone, Eq, IterBytes)]
pub struct SubpageId(uint);

View file

@ -18,6 +18,8 @@ use std::str::eq_slice;
use extra::net::url::Url; use extra::net::url::Url;
use geom::size::Size2D; use geom::size::Size2D;
use servo_msg::constellation_msg::SubpageId;
pub struct Element { pub struct Element {
parent: Node<ScriptView>, parent: Node<ScriptView>,
tag_name: ~str, // TODO: This should be an atom, not a ~str. tag_name: ~str, // TODO: This should be an atom, not a ~str.
@ -112,6 +114,7 @@ pub struct HTMLHeadingElement {
pub struct HTMLIframeElement { pub struct HTMLIframeElement {
parent: Element, parent: Element,
frame: Option<Url>, frame: Option<Url>,
subpage_id: Option<SubpageId>,
size_future_chan: Option<ChanOne<Size2D<uint>>>, size_future_chan: Option<ChanOne<Size2D<uint>>>,
} }

View file

@ -42,6 +42,7 @@ use std::str::eq_slice;
use std::result; use std::result;
use std::task; use std::task;
use hubbub::hubbub; use hubbub::hubbub;
use servo_msg::constellation_msg::SubpageId;
use servo_net::image_cache_task::ImageCacheTask; use servo_net::image_cache_task::ImageCacheTask;
use servo_net::image_cache_task; use servo_net::image_cache_task;
use servo_net::resource_task::{Done, Load, Payload, ResourceTask}; use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
@ -83,7 +84,7 @@ enum JSMessage {
pub struct HtmlParserResult { pub struct HtmlParserResult {
root: AbstractNode<ScriptView>, root: AbstractNode<ScriptView>,
style_port: Port<Stylesheet>, style_port: Port<Stylesheet>,
iframe_port: Port<(Url, Future<Size2D<uint>>)>, iframe_port: Port<(Url, SubpageId, Future<Size2D<uint>>)>,
js_port: Port<JSResult>, 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, "ul", HTMLUListElementTypeId, HTMLUListElement, []);
handle_element!(cx, tag, "img", HTMLImageElementTypeId, HTMLImageElement, [(image: None)]); 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, "h1", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading1)]);
handle_element!(cx, tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]); handle_element!(cx, tag, "h2", HTMLHeadingElementTypeId, HTMLHeadingElement, [(level: Heading2)]);
@ -281,6 +282,8 @@ pub fn parse_html(cx: *JSContext,
let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone()); let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone());
let (iframe_port, iframe_chan) = comm::stream(); let (iframe_port, iframe_chan) = comm::stream();
let next_subpage_id = Cell::new(SubpageId(0));
parser.set_tree_handler(~hubbub::TreeHandler { parser.set_tree_handler(~hubbub::TreeHandler {
create_comment: |data: ~str| { create_comment: |data: ~str| {
debug!("create comment"); debug!("create comment");
@ -337,10 +340,18 @@ pub fn parse_html(cx: *JSContext,
for src_opt.iter().advance |src| { for src_opt.iter().advance |src| {
let iframe_url = make_url(src.clone(), Some(url2.clone())); let iframe_url = make_url(src.clone(), Some(url2.clone()));
iframe_element.frame = Some(iframe_url.clone()); iframe_element.frame = Some(iframe_url.clone());
// Size future
let (port, chan) = comm::oneshot(); let (port, chan) = comm::oneshot();
iframe_element.size_future_chan = Some(chan); iframe_element.size_future_chan = Some(chan);
let size_future = from_port(port); 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));
} }
} }
} }

View file

@ -21,7 +21,7 @@ use layout_interface::{ReflowDocumentDamage, ReflowForDisplay, ReflowGoal};
use layout_interface::ReflowMsg; use layout_interface::ReflowMsg;
use layout_interface; use layout_interface;
use servo_msg::constellation_msg::{ConstellationChan, LoadUrlMsg, NavigationDirection}; 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::{LoadIframeUrlMsg};
use servo_msg::constellation_msg; use servo_msg::constellation_msg;
@ -624,12 +624,13 @@ impl ScriptTask {
// FIXME: These should be streamed to layout as they're parsed. We don't need to stop here // FIXME: These should be streamed to layout as they're parsed. We don't need to stop here
// in the script task. // 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() { match iframe_port.try_recv() {
None => break, None => break,
Some((iframe_url, size_future)) => { Some((iframe_url, subpage_id, size_future)) => {
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url, self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
pipeline_id, pipeline_id,
subpage_id,
size_future)); size_future));
} }
} }
@ -652,9 +653,10 @@ impl ScriptTask {
Left(Some(sheet)) => { Left(Some(sheet)) => {
page.layout_chan.send(AddStylesheetMsg(sheet)); page.layout_chan.send(AddStylesheetMsg(sheet));
} }
Right(Some((iframe_url, size_future))) => { Right(Some((iframe_url, subpage_id, size_future))) => {
self.constellation_chan.send(LoadIframeUrlMsg(iframe_url, self.constellation_chan.send(LoadIframeUrlMsg(iframe_url,
pipeline_id, pipeline_id,
subpage_id,
size_future)); size_future));
} }
Right(None) => { Right(None) => {