mirror of
https://github.com/servo/servo.git
synced 2025-06-25 09:34:32 +01:00
Auto merge of #14211 - asajeffrey:constellation-share-more-script-threads, r=jdm
Share script threads by tab and by eTLD+1 <!-- Please describe your changes on the following line: --> This PR shares script threads among all similar-origin documents in the same tab. This allows DOM object to be shared among same-origin same-tab documents. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #633. - [X] These changes do not require tests because refactoring. <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14211) <!-- Reviewable:end -->
This commit is contained in:
commit
1535f84bf1
5 changed files with 102 additions and 88 deletions
|
@ -32,6 +32,7 @@ use msg::constellation_msg::{Key, KeyModifiers, KeyState};
|
||||||
use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection};
|
use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, TraversalDirection};
|
||||||
use net_traits::{self, IpcSend, ResourceThreads};
|
use net_traits::{self, IpcSend, ResourceThreads};
|
||||||
use net_traits::image_cache_thread::ImageCacheThread;
|
use net_traits::image_cache_thread::ImageCacheThread;
|
||||||
|
use net_traits::pub_domains::reg_suffix;
|
||||||
use net_traits::storage_thread::{StorageThreadMsg, StorageType};
|
use net_traits::storage_thread::{StorageThreadMsg, StorageType};
|
||||||
use offscreen_gl_context::{GLContextAttributes, GLLimits};
|
use offscreen_gl_context::{GLContextAttributes, GLLimits};
|
||||||
use pipeline::{ChildProcess, InitialPipelineState, Pipeline};
|
use pipeline::{ChildProcess, InitialPipelineState, Pipeline};
|
||||||
|
@ -54,7 +55,7 @@ use std::iter::once;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::rc::Rc;
|
use std::rc::{Rc, Weak};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
@ -133,6 +134,11 @@ pub struct Constellation<Message, LTF, STF> {
|
||||||
/// to receive sw manager message
|
/// to receive sw manager message
|
||||||
swmanager_receiver: Receiver<SWManagerMsg>,
|
swmanager_receiver: Receiver<SWManagerMsg>,
|
||||||
|
|
||||||
|
/// A map from top-level frame id and registered domain name to script channels.
|
||||||
|
/// This double indirection ensures that separate tabs do not share script threads,
|
||||||
|
/// even if the same domain is loaded in each.
|
||||||
|
script_channels: HashMap<FrameId, HashMap<String, Weak<ScriptChan>>>,
|
||||||
|
|
||||||
/// A list of all the pipelines. (See the `pipeline` module for more details.)
|
/// A list of all the pipelines. (See the `pipeline` module for more details.)
|
||||||
pipelines: HashMap<PipelineId, Pipeline>,
|
pipelines: HashMap<PipelineId, Pipeline>,
|
||||||
|
|
||||||
|
@ -484,6 +490,14 @@ fn log_entry(record: &LogRecord) -> Option<LogEntry> {
|
||||||
|
|
||||||
const WARNINGS_BUFFER_SIZE: usize = 32;
|
const WARNINGS_BUFFER_SIZE: usize = 32;
|
||||||
|
|
||||||
|
/// The registered domain name (aka eTLD+1) for a URL.
|
||||||
|
/// Returns None if the URL has no host name.
|
||||||
|
/// Returns the registered suffix for the host name if it is a domain.
|
||||||
|
/// Leaves the host name alone if it is an IP address.
|
||||||
|
fn reg_host<'a>(url: &'a ServoUrl) -> Option<&'a str> {
|
||||||
|
url.domain().map(reg_suffix).or(url.host_str())
|
||||||
|
}
|
||||||
|
|
||||||
impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
where LTF: LayoutThreadFactory<Message=Message>,
|
where LTF: LayoutThreadFactory<Message=Message>,
|
||||||
STF: ScriptThreadFactory<Message=Message>
|
STF: ScriptThreadFactory<Message=Message>
|
||||||
|
@ -523,6 +537,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
swmanager_chan: None,
|
swmanager_chan: None,
|
||||||
swmanager_receiver: swmanager_receiver,
|
swmanager_receiver: swmanager_receiver,
|
||||||
swmanager_sender: sw_mgr_clone,
|
swmanager_sender: sw_mgr_clone,
|
||||||
|
script_channels: HashMap::new(),
|
||||||
pipelines: HashMap::new(),
|
pipelines: HashMap::new(),
|
||||||
frames: HashMap::new(),
|
frames: HashMap::new(),
|
||||||
pending_frames: vec!(),
|
pending_frames: vec!(),
|
||||||
|
@ -584,26 +599,50 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
frame_id: FrameId,
|
frame_id: FrameId,
|
||||||
parent_info: Option<(PipelineId, FrameType)>,
|
parent_info: Option<(PipelineId, FrameType)>,
|
||||||
old_pipeline_id: Option<PipelineId>,
|
|
||||||
initial_window_size: Option<TypedSize2D<f32, PagePx>>,
|
initial_window_size: Option<TypedSize2D<f32, PagePx>>,
|
||||||
script_channel: Option<Rc<ScriptChan>>,
|
|
||||||
load_data: LoadData,
|
load_data: LoadData,
|
||||||
|
sandbox: IFrameSandboxState,
|
||||||
is_private: bool) {
|
is_private: bool) {
|
||||||
if self.shutting_down { return; }
|
if self.shutting_down { return; }
|
||||||
|
|
||||||
|
// TODO: can we get a case where the child pipeline is created
|
||||||
|
// before the parent is part of the frame tree?
|
||||||
|
let top_level_frame_id = match parent_info {
|
||||||
|
Some((_, FrameType::MozBrowserIFrame)) => frame_id,
|
||||||
|
Some((parent_id, _)) => self.get_top_level_frame_for_pipeline(parent_id),
|
||||||
|
None => self.root_frame_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (script_channel, host) = match sandbox {
|
||||||
|
IFrameSandboxState::IFrameSandboxed => (None, None),
|
||||||
|
IFrameSandboxState::IFrameUnsandboxed => match reg_host(&load_data.url) {
|
||||||
|
None => (None, None),
|
||||||
|
Some(host) => {
|
||||||
|
let script_channel = self.script_channels.get(&top_level_frame_id)
|
||||||
|
.and_then(|map| map.get(host))
|
||||||
|
.and_then(|weak| weak.upgrade());
|
||||||
|
match script_channel {
|
||||||
|
None => (None, Some(String::from(host))),
|
||||||
|
Some(script_channel) => (Some(script_channel.clone()), None),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let resource_threads = if is_private {
|
let resource_threads = if is_private {
|
||||||
self.private_resource_threads.clone()
|
self.private_resource_threads.clone()
|
||||||
} else {
|
} else {
|
||||||
self.public_resource_threads.clone()
|
self.public_resource_threads.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let prev_visibility = if let Some(id) = old_pipeline_id {
|
let parent_visibility = parent_info
|
||||||
self.pipelines.get(&id).map(|pipeline| pipeline.visible)
|
.and_then(|(parent_pipeline_id, _)| self.pipelines.get(&parent_pipeline_id))
|
||||||
} else if let Some((parent_pipeline_id, _)) = parent_info {
|
.map(|pipeline| pipeline.visible);
|
||||||
self.pipelines.get(&parent_pipeline_id).map(|pipeline| pipeline.visible)
|
|
||||||
} else {
|
let prev_visibility = self.frames.get(&frame_id)
|
||||||
None
|
.and_then(|frame| self.pipelines.get(&frame.current.pipeline_id))
|
||||||
};
|
.map(|pipeline| pipeline.visible)
|
||||||
|
.or(parent_visibility);
|
||||||
|
|
||||||
// TODO: think about the case where the child pipeline is created
|
// TODO: think about the case where the child pipeline is created
|
||||||
// before the parent is part of the frame tree.
|
// before the parent is part of the frame tree.
|
||||||
|
@ -649,6 +688,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
self.child_processes.push(child_process);
|
self.child_processes.push(child_process);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(host) = host {
|
||||||
|
self.script_channels.entry(top_level_frame_id)
|
||||||
|
.or_insert_with(HashMap::new)
|
||||||
|
.insert(host, Rc::downgrade(&pipeline.script_chan));
|
||||||
|
}
|
||||||
|
|
||||||
assert!(!self.pipelines.contains_key(&pipeline_id));
|
assert!(!self.pipelines.contains_key(&pipeline_id));
|
||||||
self.pipelines.insert(pipeline_id, pipeline);
|
self.pipelines.insert(pipeline_id, pipeline);
|
||||||
}
|
}
|
||||||
|
@ -1199,13 +1244,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// Notify the browser chrome that the pipeline has failed
|
// Notify the browser chrome that the pipeline has failed
|
||||||
self.trigger_mozbrowsererror(top_level_frame_id, reason, backtrace);
|
self.trigger_mozbrowsererror(top_level_frame_id, reason, backtrace);
|
||||||
|
|
||||||
let frame_id = FrameId::from(top_level_frame_id);
|
let pipeline_id = self.frames.get(&top_level_frame_id).map(|frame| frame.current.pipeline_id);
|
||||||
let pipeline_id = self.frames.get(&frame_id).map(|frame| frame.current.pipeline_id);
|
|
||||||
let pipeline_url = pipeline_id.and_then(|id| self.pipelines.get(&id).map(|pipeline| pipeline.url.clone()));
|
let pipeline_url = pipeline_id.and_then(|id| self.pipelines.get(&id).map(|pipeline| pipeline.url.clone()));
|
||||||
let parent_info = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.parent_info));
|
let parent_info = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.parent_info));
|
||||||
let window_size = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.size));
|
let window_size = pipeline_id.and_then(|id| self.pipelines.get(&id).and_then(|pipeline| pipeline.size));
|
||||||
|
|
||||||
self.close_frame_children(frame_id, ExitPipelineMode::Force);
|
self.close_frame_children(top_level_frame_id, ExitPipelineMode::Force);
|
||||||
|
|
||||||
let failure_url = ServoUrl::parse("about:failure").expect("infallible");
|
let failure_url = ServoUrl::parse("about:failure").expect("infallible");
|
||||||
|
|
||||||
|
@ -1219,11 +1263,10 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
let new_pipeline_id = PipelineId::new();
|
let new_pipeline_id = PipelineId::new();
|
||||||
let load_data = LoadData::new(failure_url, None, None);
|
let load_data = LoadData::new(failure_url, None, None);
|
||||||
self.new_pipeline(new_pipeline_id, frame_id, parent_info, pipeline_id,
|
let sandbox = IFrameSandboxState::IFrameSandboxed;
|
||||||
window_size, None, load_data, false);
|
self.new_pipeline(new_pipeline_id, top_level_frame_id, parent_info, window_size, load_data, sandbox, false);
|
||||||
|
|
||||||
self.pending_frames.push(FrameChange {
|
self.pending_frames.push(FrameChange {
|
||||||
frame_id: frame_id,
|
frame_id: top_level_frame_id,
|
||||||
old_pipeline_id: pipeline_id,
|
old_pipeline_id: pipeline_id,
|
||||||
new_pipeline_id: new_pipeline_id,
|
new_pipeline_id: new_pipeline_id,
|
||||||
document_ready: false,
|
document_ready: false,
|
||||||
|
@ -1252,8 +1295,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let window_size = self.window_size.visible_viewport;
|
let window_size = self.window_size.visible_viewport;
|
||||||
let root_pipeline_id = PipelineId::new();
|
let root_pipeline_id = PipelineId::new();
|
||||||
let root_frame_id = self.root_frame_id;
|
let root_frame_id = self.root_frame_id;
|
||||||
self.new_pipeline(root_pipeline_id, root_frame_id, None, None, Some(window_size), None,
|
let load_data = LoadData::new(url.clone(), None, None);
|
||||||
LoadData::new(url.clone(), None, None), false);
|
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
||||||
|
self.new_pipeline(root_pipeline_id, root_frame_id, None, Some(window_size), load_data, sandbox, false);
|
||||||
self.handle_load_start_msg(root_pipeline_id);
|
self.handle_load_start_msg(root_pipeline_id);
|
||||||
self.pending_frames.push(FrameChange {
|
self.pending_frames.push(FrameChange {
|
||||||
frame_id: self.root_frame_id,
|
frame_id: self.root_frame_id,
|
||||||
|
@ -1320,7 +1364,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
// parent_pipeline_id's frame tree's children. This message is never the result of a
|
// parent_pipeline_id's frame tree's children. This message is never the result of a
|
||||||
// page navigation.
|
// page navigation.
|
||||||
fn handle_script_loaded_url_in_iframe_msg(&mut self, load_info: IFrameLoadInfo) {
|
fn handle_script_loaded_url_in_iframe_msg(&mut self, load_info: IFrameLoadInfo) {
|
||||||
let (load_data, script_chan, window_size, is_private) = {
|
let (load_data, window_size, is_private) = {
|
||||||
let old_pipeline = load_info.old_pipeline_id
|
let old_pipeline = load_info.old_pipeline_id
|
||||||
.and_then(|old_pipeline_id| self.pipelines.get(&old_pipeline_id));
|
.and_then(|old_pipeline_id| self.pipelines.get(&old_pipeline_id));
|
||||||
|
|
||||||
|
@ -1340,47 +1384,24 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
LoadData::new(url, None, None)
|
LoadData::new(url, None, None)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Compare the pipeline's url to the new url. If the origin is the same,
|
|
||||||
// then reuse the script thread in creating the new pipeline
|
|
||||||
let source_url = &source_pipeline.url;
|
|
||||||
|
|
||||||
let is_private = load_info.is_private || source_pipeline.is_private;
|
let is_private = load_info.is_private || source_pipeline.is_private;
|
||||||
|
|
||||||
// FIXME(#10968): this should probably match the origin check in
|
|
||||||
// HTMLIFrameElement::contentDocument.
|
|
||||||
let same_script = source_url.host() == load_data.url.host() &&
|
|
||||||
source_url.port() == load_data.url.port() &&
|
|
||||||
load_info.sandbox == IFrameSandboxState::IFrameUnsandboxed &&
|
|
||||||
source_pipeline.is_private == is_private;
|
|
||||||
|
|
||||||
// Reuse the script thread if the URL is same-origin
|
|
||||||
let script_chan = if same_script {
|
|
||||||
debug!("Constellation: loading same-origin iframe, \
|
|
||||||
parent url {:?}, iframe url {:?}", source_url, load_data.url);
|
|
||||||
Some(source_pipeline.script_chan.clone())
|
|
||||||
} else {
|
|
||||||
debug!("Constellation: loading cross-origin iframe, \
|
|
||||||
parent url {:?}, iframe url {:?}", source_url, load_data.url);
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let window_size = old_pipeline.and_then(|old_pipeline| old_pipeline.size);
|
let window_size = old_pipeline.and_then(|old_pipeline| old_pipeline.size);
|
||||||
|
|
||||||
if let Some(old_pipeline) = old_pipeline {
|
if let Some(old_pipeline) = old_pipeline {
|
||||||
old_pipeline.freeze();
|
old_pipeline.freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
(load_data, script_chan, window_size, is_private)
|
(load_data, window_size, is_private)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the new pipeline, attached to the parent and push to pending frames
|
// Create the new pipeline, attached to the parent and push to pending frames
|
||||||
self.new_pipeline(load_info.new_pipeline_id,
|
self.new_pipeline(load_info.new_pipeline_id,
|
||||||
load_info.frame_id,
|
load_info.frame_id,
|
||||||
Some((load_info.parent_pipeline_id, load_info.frame_type)),
|
Some((load_info.parent_pipeline_id, load_info.frame_type)),
|
||||||
load_info.old_pipeline_id,
|
|
||||||
window_size,
|
window_size,
|
||||||
script_chan,
|
|
||||||
load_data,
|
load_data,
|
||||||
|
load_info.sandbox,
|
||||||
is_private);
|
is_private);
|
||||||
|
|
||||||
self.pending_frames.push(FrameChange {
|
self.pending_frames.push(FrameChange {
|
||||||
|
@ -1517,7 +1538,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
let window_size = self.pipelines.get(&source_id).and_then(|source| source.size);
|
let window_size = self.pipelines.get(&source_id).and_then(|source| source.size);
|
||||||
let new_pipeline_id = PipelineId::new();
|
let new_pipeline_id = PipelineId::new();
|
||||||
let root_frame_id = self.root_frame_id;
|
let root_frame_id = self.root_frame_id;
|
||||||
self.new_pipeline(new_pipeline_id, root_frame_id, None, None, window_size, None, load_data, false);
|
let sandbox = IFrameSandboxState::IFrameUnsandboxed;
|
||||||
|
self.new_pipeline(new_pipeline_id, root_frame_id, None, window_size, load_data, sandbox, false);
|
||||||
self.pending_frames.push(FrameChange {
|
self.pending_frames.push(FrameChange {
|
||||||
frame_id: root_frame_id,
|
frame_id: root_frame_id,
|
||||||
old_pipeline_id: Some(source_id),
|
old_pipeline_id: Some(source_id),
|
||||||
|
@ -2272,6 +2294,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
|
||||||
|
|
||||||
self.close_frame_children(frame_id, exit_mode);
|
self.close_frame_children(frame_id, exit_mode);
|
||||||
|
|
||||||
|
self.script_channels.remove(&frame_id);
|
||||||
if self.frames.remove(&frame_id).is_none() {
|
if self.frames.remove(&frame_id).is_none() {
|
||||||
warn!("Closing frame {:?} twice.", frame_id);
|
warn!("Closing frame {:?} twice.", frame_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,8 +115,9 @@ pub struct InitialPipelineState {
|
||||||
pub window_size: Option<TypedSize2D<f32, PagePx>>,
|
pub window_size: Option<TypedSize2D<f32, PagePx>>,
|
||||||
/// Information about the device pixel ratio.
|
/// Information about the device pixel ratio.
|
||||||
pub device_pixel_ratio: ScaleFactor<f32, ViewportPx, DevicePixel>,
|
pub device_pixel_ratio: ScaleFactor<f32, ViewportPx, DevicePixel>,
|
||||||
/// A channel to the script thread, if applicable. If this is `Some`,
|
/// A channel to the script thread, if applicable.
|
||||||
/// then `parent_info` must also be `Some`.
|
/// If this is `None`, create a new script thread.
|
||||||
|
/// If this is `Some`, then reuse an existing script thread.
|
||||||
pub script_chan: Option<Rc<ScriptChan>>,
|
pub script_chan: Option<Rc<ScriptChan>>,
|
||||||
/// Information about the page to load.
|
/// Information about the page to load.
|
||||||
pub load_data: LoadData,
|
pub load_data: LoadData,
|
||||||
|
@ -146,16 +147,23 @@ impl Pipeline {
|
||||||
let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) =
|
let (layout_content_process_shutdown_chan, layout_content_process_shutdown_port) =
|
||||||
ipc::channel().expect("Pipeline layout content shutdown chan");
|
ipc::channel().expect("Pipeline layout content shutdown chan");
|
||||||
|
|
||||||
|
let device_pixel_ratio = state.device_pixel_ratio;
|
||||||
|
let window_size = state.window_size.map(|size| {
|
||||||
|
WindowSizeData {
|
||||||
|
visible_viewport: size,
|
||||||
|
initial_viewport: size * ScaleFactor::new(1.0),
|
||||||
|
device_pixel_ratio: device_pixel_ratio,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let (script_chan, content_ports) = match state.script_chan {
|
let (script_chan, content_ports) = match state.script_chan {
|
||||||
Some(script_chan) => {
|
Some(script_chan) => {
|
||||||
let (parent_pipeline_id, frame_type) =
|
|
||||||
state.parent_info.expect("script_pipeline != None but parent_info == None");
|
|
||||||
let new_layout_info = NewLayoutInfo {
|
let new_layout_info = NewLayoutInfo {
|
||||||
parent_pipeline_id: parent_pipeline_id,
|
parent_info: state.parent_info,
|
||||||
new_pipeline_id: state.id,
|
new_pipeline_id: state.id,
|
||||||
frame_id: state.frame_id,
|
frame_id: state.frame_id,
|
||||||
frame_type: frame_type,
|
|
||||||
load_data: state.load_data.clone(),
|
load_data: state.load_data.clone(),
|
||||||
|
window_size: window_size,
|
||||||
pipeline_port: pipeline_port,
|
pipeline_port: pipeline_port,
|
||||||
layout_to_constellation_chan: state.layout_to_constellation_chan.clone(),
|
layout_to_constellation_chan: state.layout_to_constellation_chan.clone(),
|
||||||
content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(),
|
content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(),
|
||||||
|
@ -191,15 +199,6 @@ impl Pipeline {
|
||||||
script_to_devtools_chan
|
script_to_devtools_chan
|
||||||
});
|
});
|
||||||
|
|
||||||
let device_pixel_ratio = state.device_pixel_ratio;
|
|
||||||
let window_size = state.window_size.map(|size| {
|
|
||||||
WindowSizeData {
|
|
||||||
visible_viewport: size,
|
|
||||||
initial_viewport: size * ScaleFactor::new(1.0),
|
|
||||||
device_pixel_ratio: device_pixel_ratio,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let (script_content_process_shutdown_chan, script_content_process_shutdown_port) =
|
let (script_content_process_shutdown_chan, script_content_process_shutdown_port) =
|
||||||
ipc::channel().expect("Pipeline script content process shutdown chan");
|
ipc::channel().expect("Pipeline script content process shutdown chan");
|
||||||
|
|
||||||
|
|
|
@ -1173,11 +1173,11 @@ impl ScriptThread {
|
||||||
|
|
||||||
fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) {
|
fn handle_new_layout(&self, new_layout_info: NewLayoutInfo) {
|
||||||
let NewLayoutInfo {
|
let NewLayoutInfo {
|
||||||
parent_pipeline_id,
|
parent_info,
|
||||||
new_pipeline_id,
|
new_pipeline_id,
|
||||||
frame_id,
|
frame_id,
|
||||||
frame_type,
|
|
||||||
load_data,
|
load_data,
|
||||||
|
window_size,
|
||||||
pipeline_port,
|
pipeline_port,
|
||||||
layout_to_constellation_chan,
|
layout_to_constellation_chan,
|
||||||
content_process_shutdown_chan,
|
content_process_shutdown_chan,
|
||||||
|
@ -1187,7 +1187,7 @@ impl ScriptThread {
|
||||||
let layout_pair = channel();
|
let layout_pair = channel();
|
||||||
let layout_chan = layout_pair.0.clone();
|
let layout_chan = layout_pair.0.clone();
|
||||||
|
|
||||||
let layout_creation_info = NewLayoutThreadInfo {
|
let msg = message::Msg::CreateLayoutThread(NewLayoutThreadInfo {
|
||||||
id: new_pipeline_id,
|
id: new_pipeline_id,
|
||||||
url: load_data.url.clone(),
|
url: load_data.url.clone(),
|
||||||
is_parent: false,
|
is_parent: false,
|
||||||
|
@ -1198,19 +1198,18 @@ impl ScriptThread {
|
||||||
image_cache_thread: self.image_cache_thread.clone(),
|
image_cache_thread: self.image_cache_thread.clone(),
|
||||||
content_process_shutdown_chan: content_process_shutdown_chan,
|
content_process_shutdown_chan: content_process_shutdown_chan,
|
||||||
layout_threads: layout_threads,
|
layout_threads: layout_threads,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Pick a layout thread, any layout thread
|
||||||
|
match self.documents.borrow().iter().next() {
|
||||||
|
None => panic!("Layout attached to empty script thread."),
|
||||||
|
// Tell the layout thread factory to actually spawn the thread.
|
||||||
|
Some((_, document)) => document.window().layout_chan().send(msg).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent_window = self.documents.borrow().find_window(parent_pipeline_id)
|
|
||||||
.expect("ScriptThread: received a layout for a parent pipeline not in this script thread. This is a bug.");
|
|
||||||
|
|
||||||
// Tell layout to actually spawn the thread.
|
|
||||||
parent_window.layout_chan()
|
|
||||||
.send(message::Msg::CreateLayoutThread(layout_creation_info))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Kick off the fetch for the new resource.
|
// Kick off the fetch for the new resource.
|
||||||
let new_load = InProgressLoad::new(new_pipeline_id, frame_id, Some((parent_pipeline_id, frame_type)),
|
let new_load = InProgressLoad::new(new_pipeline_id, frame_id, parent_info,
|
||||||
layout_chan, parent_window.window_size(),
|
layout_chan, window_size,
|
||||||
load_data.url.clone());
|
load_data.url.clone());
|
||||||
self.start_page_load(new_load, load_data);
|
self.start_page_load(new_load, load_data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,19 +162,20 @@ impl LoadData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The initial data associated with a newly-created framed pipeline.
|
/// The initial data required to create a new layout attached to an existing script thread.
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct NewLayoutInfo {
|
pub struct NewLayoutInfo {
|
||||||
/// Id of the parent of this new pipeline.
|
/// The ID of the parent pipeline and frame type, if any.
|
||||||
pub parent_pipeline_id: PipelineId,
|
/// If `None`, this is a root pipeline.
|
||||||
|
pub parent_info: Option<(PipelineId, FrameType)>,
|
||||||
/// Id of the newly-created pipeline.
|
/// Id of the newly-created pipeline.
|
||||||
pub new_pipeline_id: PipelineId,
|
pub new_pipeline_id: PipelineId,
|
||||||
/// Id of the frame associated with this pipeline.
|
/// Id of the frame associated with this pipeline.
|
||||||
pub frame_id: FrameId,
|
pub frame_id: FrameId,
|
||||||
/// Type of the frame associated with this pipeline.
|
|
||||||
pub frame_type: FrameType,
|
|
||||||
/// Network request data which will be initiated by the script thread.
|
/// Network request data which will be initiated by the script thread.
|
||||||
pub load_data: LoadData,
|
pub load_data: LoadData,
|
||||||
|
/// Information about the initial window size.
|
||||||
|
pub window_size: Option<WindowSizeData>,
|
||||||
/// A port on which layout can receive messages from the pipeline.
|
/// A port on which layout can receive messages from the pipeline.
|
||||||
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
|
pub pipeline_port: IpcReceiver<LayoutControlMsg>,
|
||||||
/// A sender for the layout thread to communicate to the constellation.
|
/// A sender for the layout thread to communicate to the constellation.
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
[cross_origin_parentage.html]
|
|
||||||
type: testharness
|
|
||||||
[Check the frame heriarchy 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Check the frame heriarchy 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue