mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
added subpage ids to map from iframe to all associated pipelines
This commit is contained in:
parent
a2bdab7989
commit
2348fbf46d
6 changed files with 71 additions and 47 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue