IFrame elements now manage FrameIds rather than the constellation.

This commit is contained in:
Alan Jeffrey 2016-09-28 19:45:39 -05:00
parent 86f31d0dc7
commit f53408df80
7 changed files with 169 additions and 177 deletions

View file

@ -139,14 +139,11 @@ pub struct Constellation<Message, LTF, STF> {
font_cache_thread: FontCacheThread,
/// ID of the root frame.
root_frame_id: Option<FrameId>,
root_frame_id: FrameId,
/// The next free ID to assign to a pipeline ID namespace.
next_pipeline_namespace_id: PipelineNamespaceId,
/// The next free ID to assign to a frame.
next_frame_id: FrameId,
/// Pipeline ID that has currently focused element for key events.
focus_pipeline_id: Option<PipelineId>,
@ -268,6 +265,7 @@ impl Frame {
/// Represents a pending change in the frame tree, that will be applied
/// once the new pipeline has loaded and completed initial layout / paint.
struct FrameChange {
frame_id: FrameId,
old_pipeline_id: Option<PipelineId>,
new_pipeline_id: PipelineId,
document_ready: bool,
@ -476,6 +474,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let swmanager_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(swmanager_receiver);
PipelineNamespace::install(PipelineNamespaceId(0));
let mut constellation: Constellation<Message, LTF, STF> = Constellation {
script_sender: ipc_script_sender,
layout_sender: ipc_layout_sender,
@ -495,9 +495,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
pipelines: HashMap::new(),
frames: HashMap::new(),
pending_frames: vec!(),
next_pipeline_namespace_id: PipelineNamespaceId(0),
root_frame_id: None,
next_frame_id: FrameId(0),
// We initialize the namespace at 1, since we reserved namespace 0 for the constellation
next_pipeline_namespace_id: PipelineNamespaceId(1),
root_frame_id: FrameId::new(),
focus_pipeline_id: None,
time_profiler_chan: state.time_profiler_chan,
mem_profiler_chan: state.mem_profiler_chan,
@ -525,8 +525,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
(rng, prob)
}),
};
let namespace_id = constellation.next_pipeline_namespace_id();
PipelineNamespace::install(namespace_id);
constellation.run();
});
(compositor_sender, swmanager_sender)
@ -614,9 +613,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Get an iterator for the current frame tree. Specify self.root_frame_id to
// iterate the entire tree, or a specific frame id to iterate only that sub-tree.
fn current_frame_tree_iter(&self, frame_id_root: Option<FrameId>) -> FrameTreeIterator {
fn current_frame_tree_iter(&self, frame_id_root: FrameId) -> FrameTreeIterator {
FrameTreeIterator {
stack: frame_id_root.into_iter().collect(),
stack: vec!(frame_id_root),
pipelines: &self.pipelines,
frames: &self.frames,
}
@ -656,20 +655,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
// Create a new frame and update the internal bookkeeping.
fn new_frame(&mut self, pipeline_id: PipelineId) -> FrameId {
let id = self.next_frame_id;
let FrameId(ref mut i) = self.next_frame_id;
*i += 1;
let frame = Frame::new(id, pipeline_id);
fn new_frame(&mut self, frame_id: FrameId, pipeline_id: PipelineId) {
let frame = Frame::new(frame_id, pipeline_id);
assert!(self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.frame).is_none());
assert!(!self.frames.contains_key(&id));
assert!(!self.frames.contains_key(&frame_id));
self.pipelines.get_mut(&pipeline_id).map(|pipeline| pipeline.frame = Some(id));
self.frames.insert(id, frame);
id
self.pipelines.get_mut(&pipeline_id).map(|pipeline| pipeline.frame = Some(frame_id));
self.frames.insert(frame_id, frame);
}
/// Handles loading pages, navigation, and granting access to the compositor
@ -1032,10 +1025,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
if self.shutting_down { return; }
self.shutting_down = true;
// TODO: exit before the root frame is set?
if let Some(root_id) = self.root_frame_id {
self.close_frame(root_id, ExitPipelineMode::Normal);
}
// TODO: exit before the root frame is initialized?
let root_frame_id = self.root_frame_id;
self.close_frame(root_frame_id, ExitPipelineMode::Normal);
}
fn handle_shutdown(&mut self) {
@ -1121,6 +1113,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let pipeline_url = self.pipelines.get(&pipeline_id).map(|pipeline| pipeline.url.clone());
let parent_info = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.parent_info);
let window_size = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.size);
let frame_id = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.frame);
self.close_pipeline(pipeline_id, ExitPipelineMode::Force);
self.pipelines.remove(&pipeline_id);
@ -1142,11 +1135,13 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
warn!("creating replacement pipeline for about:failure");
if let Some(frame_id) = frame_id {
let new_pipeline_id = PipelineId::new();
let load_data = LoadData::new(failure_url, None, None);
self.new_pipeline(new_pipeline_id, parent_info, Some(pipeline_id), window_size, None, load_data, false);
self.pending_frames.push(FrameChange {
frame_id: frame_id,
old_pipeline_id: Some(pipeline_id),
new_pipeline_id: new_pipeline_id,
document_ready: false,
@ -1154,6 +1149,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
});
}
}
}
fn handle_log_entry(&mut self, pipeline_id: Option<PipelineId>, thread_name: Option<String>, entry: LogEntry) {
debug!("Received log entry {:?}.", entry);
@ -1172,11 +1168,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
fn handle_init_load(&mut self, url: Url) {
let window_size = self.window_size.visible_viewport;
let root_pipeline_id = PipelineId::new();
debug_assert!(PipelineId::fake_root_pipeline_id() == root_pipeline_id);
self.new_pipeline(root_pipeline_id, None, None, Some(window_size), None,
LoadData::new(url.clone(), None, None), false);
self.handle_load_start_msg(root_pipeline_id);
self.pending_frames.push(FrameChange {
frame_id: self.root_frame_id,
old_pipeline_id: None,
new_pipeline_id: root_pipeline_id,
document_ready: false,
@ -1304,6 +1300,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
is_private);
self.pending_frames.push(FrameChange {
frame_id: load_info.frame_id,
old_pipeline_id: load_info.old_pipeline_id,
new_pipeline_id: load_info.new_pipeline_id,
document_ready: false,
@ -1351,8 +1348,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let display_alert_dialog = if PREFS.is_mozbrowser_enabled() {
let parent_pipeline_info = self.pipelines.get(&pipeline_id).and_then(|source| source.parent_info);
if parent_pipeline_info.is_some() {
let root_pipeline_id = self.root_frame_id
.and_then(|root_frame_id| self.frames.get(&root_frame_id))
let root_pipeline_id = self.frames.get(&self.root_frame_id)
.map(|root_frame| root_frame.current.pipeline_id);
let ancestor_info = self.get_mozbrowser_ancestor_info(pipeline_id);
@ -1441,6 +1437,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
let new_pipeline_id = PipelineId::new();
self.new_pipeline(new_pipeline_id, None, None, window_size, None, load_data, false);
self.pending_frames.push(FrameChange {
frame_id: self.root_frame_id,
old_pipeline_id: Some(source_id),
new_pipeline_id: new_pipeline_id,
document_ready: false,
@ -1458,12 +1455,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
fn handle_load_start_msg(&mut self, pipeline_id: PipelineId) {
if let Some(frame_id) = self.get_top_level_frame_for_pipeline(Some(pipeline_id)) {
let frame_id = self.get_top_level_frame_for_pipeline(Some(pipeline_id));
let forward = !self.joint_session_future(frame_id).is_empty();
let back = !self.joint_session_past(frame_id).is_empty();
self.compositor_proxy.send(ToCompositorMsg::LoadStart(back, forward));
}
}
fn handle_load_complete_msg(&mut self, pipeline_id: PipelineId) {
let mut webdriver_reset = false;
@ -1477,22 +1473,18 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
if webdriver_reset {
self.webdriver.load_channel = None;
}
if let Some(frame_id) = self.get_top_level_frame_for_pipeline(Some(pipeline_id)) {
let frame_id = self.get_top_level_frame_for_pipeline(Some(pipeline_id));
let forward = !self.joint_session_future(frame_id).is_empty();
let back = !self.joint_session_past(frame_id).is_empty();
let root = self.root_frame_id.is_none() || self.root_frame_id == Some(frame_id);
let root = self.root_frame_id == frame_id;
self.compositor_proxy.send(ToCompositorMsg::LoadComplete(back, forward, root));
}
self.handle_subframe_loaded(pipeline_id);
}
fn handle_traverse_history_msg(&mut self,
pipeline_id: Option<PipelineId>,
direction: TraversalDirection) {
let frame_id = match self.get_top_level_frame_for_pipeline(pipeline_id) {
Some(frame_id) => frame_id,
None => return warn!("Traverse message received after root's closure."),
};
let frame_id = self.get_top_level_frame_for_pipeline(pipeline_id);
let mut traversal_info = HashMap::new();
@ -1526,14 +1518,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
fn handle_joint_session_history_length(&self, pipeline_id: PipelineId, sender: IpcSender<u32>) {
let frame_id = match self.get_top_level_frame_for_pipeline(Some(pipeline_id)) {
Some(frame_id) => frame_id,
None => {
warn!("Jsh length message received after root's closure.");
let _ = sender.send(0);
return;
},
};
let frame_id = self.get_top_level_frame_for_pipeline(Some(pipeline_id));
// Initialize length at 1 to count for the current active entry
let mut length = 1;
@ -1548,8 +1533,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Send to the explicitly focused pipeline (if it exists), or the root
// frame's current pipeline. If neither exist, fall back to sending to
// the compositor below.
let root_pipeline_id = self.root_frame_id
.and_then(|root_frame_id| self.frames.get(&root_frame_id))
let root_pipeline_id = self.frames.get(&self.root_frame_id)
.map(|root_frame| root_frame.current.pipeline_id);
let pipeline_id = self.focus_pipeline_id.or(root_pipeline_id);
@ -1574,8 +1558,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
fn handle_reload_msg(&mut self) {
// Send Reload constellation msg to root script channel.
let root_pipeline_id = self.root_frame_id
.and_then(|root_frame_id| self.frames.get(&root_frame_id))
let root_pipeline_id = self.frames.get(&self.root_frame_id)
.map(|root_frame| root_frame.current.pipeline_id);
if let Some(pipeline_id) = root_pipeline_id {
@ -1618,8 +1601,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
fn handle_get_pipeline(&mut self, frame_id: Option<FrameId>,
resp_chan: IpcSender<Option<(PipelineId, bool)>>) {
let current_pipeline_id = frame_id.or(self.root_frame_id)
.and_then(|frame_id| self.frames.get(&frame_id))
let frame_id = frame_id.unwrap_or(self.root_frame_id);
let current_pipeline_id = self.frames.get(&frame_id)
.map(|frame| frame.current.pipeline_id);
let current_pipeline_id_loaded = current_pipeline_id
.map(|id| (id, true));
@ -1793,8 +1776,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
},
WebDriverCommandMsg::TakeScreenshot(pipeline_id, reply) => {
let current_pipeline_id = self.root_frame_id
.and_then(|root_frame_id| self.frames.get(&root_frame_id))
let current_pipeline_id = self.frames.get(&self.root_frame_id)
.map(|root_frame| root_frame.current.pipeline_id);
if Some(pipeline_id) == current_pipeline_id {
self.compositor_proxy.send(ToCompositorMsg::CreatePng(reply));
@ -1898,12 +1880,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
fn get_top_level_frame_for_pipeline(&self, pipeline_id: Option<PipelineId>) -> Option<FrameId> {
fn get_top_level_frame_for_pipeline(&self, pipeline_id: Option<PipelineId>) -> FrameId {
if PREFS.is_mozbrowser_enabled() {
pipeline_id.and_then(|id| self.get_mozbrowser_ancestor_info(id))
.and_then(|pipeline_info| self.pipelines.get(&pipeline_info.1))
.and_then(|pipeline| pipeline.frame)
.or(self.root_frame_id)
.unwrap_or(self.root_frame_id)
} else {
// If mozbrowser is not enabled, the root frame is the only top-level frame
self.root_frame_id
@ -1933,51 +1915,41 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
let frame_id = frame_change.old_pipeline_id.and_then(|old_pipeline_id| {
if let Some(old_pipeline_id) = frame_change.old_pipeline_id {
// The new pipeline is replacing an old one.
// Remove paint permissions for the pipeline being replaced.
self.revoke_paint_permission(old_pipeline_id);
};
self.pipelines.get(&old_pipeline_id).and_then(|pipeline| pipeline.frame)
});
match frame_id {
Some(frame_id) => {
if self.frames.contains_key(&frame_change.frame_id) {
// Add new pipeline to navigation frame, and return frames evicted from history.
if let Some(ref mut pipeline) = self.pipelines.get_mut(&frame_change.new_pipeline_id) {
pipeline.frame = Some(frame_id);
pipeline.frame = Some(frame_change.frame_id);
}
if frame_change.replace {
let evicted = self.frames.get_mut(&frame_id).map(|frame| {
let evicted = self.frames.get_mut(&frame_change.frame_id).map(|frame| {
frame.replace_current(frame_change.new_pipeline_id)
});
if let Some(evicted) = evicted {
self.close_pipeline(evicted.pipeline_id, ExitPipelineMode::Normal);
}
} else {
if let Some(ref mut frame) = self.frames.get_mut(&frame_id) {
if let Some(ref mut frame) = self.frames.get_mut(&frame_change.frame_id) {
frame.load(frame_change.new_pipeline_id);
}
}
}
None => {
} else {
// The new pipeline is in a new frame with no history
let frame_id = self.new_frame(frame_change.new_pipeline_id);
self.new_frame(frame_change.frame_id, frame_change.new_pipeline_id);
// If a child frame, add it to the parent pipeline. Otherwise
// it must surely be the root frame being created!
match self.pipelines.get(&frame_change.new_pipeline_id)
.and_then(|pipeline| pipeline.parent_info) {
Some((parent_id, _)) => {
let parent_info = self.pipelines.get(&frame_change.new_pipeline_id)
.and_then(|pipeline| pipeline.parent_info);
if let Some((parent_id, _)) = parent_info {
if let Some(parent) = self.pipelines.get_mut(&parent_id) {
parent.add_child(frame_id);
}
}
None => {
assert!(self.root_frame_id.is_none());
self.root_frame_id = Some(frame_id);
}
parent.add_child(frame_change.frame_id);
}
}
}
@ -1987,11 +1959,8 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// This is the result of a link being clicked and a navigation completing.
self.trigger_mozbrowserlocationchange(frame_change.new_pipeline_id);
let frame_id = match self.get_top_level_frame_for_pipeline(Some(frame_change.new_pipeline_id)) {
Some(frame_id) => frame_id,
None => return warn!("Tried to remove forward history after root frame closure."),
};
self.clear_joint_session_future(frame_id);
let top_level_frame_id = self.get_top_level_frame_for_pipeline(Some(frame_change.new_pipeline_id));
self.clear_joint_session_future(top_level_frame_id);
}
// Build frame tree and send permission
@ -2052,13 +2021,9 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
debug!("handle_window_size_msg: {:?} {:?}", new_size.initial_viewport.to_untyped(),
new_size.visible_viewport.to_untyped());
if let Some(root_frame_id) = self.root_frame_id {
if let Some(frame) = self.frames.get(&self.root_frame_id) {
// Send Resize (or ResizeInactive) messages to each
// pipeline in the frame tree.
let frame = match self.frames.get(&root_frame_id) {
None => return warn!("Frame {:?} resized after closing.", root_frame_id),
Some(frame) => frame,
};
let pipeline_id = frame.current.pipeline_id;
let pipeline = match self.pipelines.get(&pipeline_id) {
None => return warn!("Pipeline {:?} resized after closing.", pipeline_id),
@ -2127,7 +2092,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
//
// If there is no root frame yet, the initial page has
// not loaded, so there is nothing to save yet.
if self.root_frame_id.is_none() {
if !self.frames.contains_key(&self.root_frame_id) {
return ReadyToSave::NoRootFrame;
}
@ -2384,11 +2349,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Revoke paint permission from a pipeline, and all children.
fn revoke_paint_permission(&self, pipeline_id: PipelineId) {
let frame_id = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.frame);
if let Some(frame_id) = self.pipelines.get(&pipeline_id).and_then(|pipeline| pipeline.frame) {
for frame in self.current_frame_tree_iter(frame_id) {
self.pipelines.get(&frame.current.pipeline_id).map(|pipeline| pipeline.revoke_paint_permission());
}
}
}
// Send the current frame tree to compositor, and grant paint
// permission to each pipeline in the current frame tree.
@ -2396,8 +2362,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// Note that this function can panic, due to ipc-channel creation failure.
// avoiding this panic would require a mechanism for dealing
// with low-resource scenarios.
if let Some(root_frame_id) = self.root_frame_id {
if let Some(frame_tree) = self.frame_to_sendable(root_frame_id) {
if let Some(frame_tree) = self.frame_to_sendable(self.root_frame_id) {
let (chan, port) = ipc::channel().expect("Failed to create IPC channel!");
self.compositor_proxy.send(ToCompositorMsg::SetFrameTree(frame_tree,
chan));
@ -2406,7 +2371,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
return; // Our message has been discarded, probably shutting down.
}
}
}
for frame in self.current_frame_tree_iter(self.root_frame_id) {
self.pipelines.get(&frame.current.pipeline_id).map(|pipeline| pipeline.grant_paint_permission());
@ -2489,20 +2453,18 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
if let Some(root_frame_id) = self.root_frame_id {
if let Some(root_frame) = self.frames.get(&root_frame_id) {
if let Some(root_frame) = self.frames.get(&self.root_frame_id) {
if let Some(root_pipeline) = self.pipelines.get(&root_frame.current.pipeline_id) {
return root_pipeline.trigger_mozbrowser_event(None, event);
}
}
}
warn!("Mozbrowser error after root pipeline closed.");
}
fn focused_pipeline_in_tree(&self, frame_id: FrameId) -> bool {
self.focus_pipeline_id.map_or(false, |pipeline_id| {
self.pipeline_exists_in_tree(pipeline_id, Some(frame_id))
self.pipeline_exists_in_tree(pipeline_id, frame_id)
})
}
@ -2512,7 +2474,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
fn pipeline_exists_in_tree(&self,
pipeline_id: PipelineId,
root_frame_id: Option<FrameId>) -> bool {
root_frame_id: FrameId) -> bool {
self.current_frame_tree_iter(root_frame_id)
.any(|current_frame| current_frame.current.pipeline_id == pipeline_id)
}

View file

@ -221,9 +221,6 @@ pub enum TraversalDirection {
Back(usize),
}
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, PartialOrd, Ord)]
pub struct FrameId(pub u32);
/// Each pipeline ID needs to be unique. However, it also needs to be possible to
/// generate the pipeline ID from an iframe element (this simplifies a lot of other
/// code that makes use of pipeline IDs).
@ -242,7 +239,7 @@ pub struct FrameId(pub u32);
#[derive(Clone, Copy)]
pub struct PipelineNamespace {
id: PipelineNamespaceId,
next_index: PipelineIndex,
index: u32,
}
impl PipelineNamespace {
@ -251,21 +248,29 @@ impl PipelineNamespace {
assert!(tls.get().is_none());
tls.set(Some(PipelineNamespace {
id: namespace_id,
next_index: PipelineIndex(0),
index: 0,
}));
});
}
fn next(&mut self) -> PipelineId {
let pipeline_id = PipelineId {
fn next_index(&mut self) -> u32 {
let result = self.index;
self.index = result + 1;
result
}
fn next_pipeline_id(&mut self) -> PipelineId {
PipelineId {
namespace_id: self.id,
index: self.next_index,
};
index: PipelineIndex(self.next_index()),
}
}
let PipelineIndex(current_index) = self.next_index;
self.next_index = PipelineIndex(current_index + 1);
pipeline_id
fn next_frame_id(&mut self) -> FrameId {
FrameId {
namespace_id: self.id,
index: FrameIndex(self.next_index()),
}
}
}
@ -289,24 +294,12 @@ impl PipelineId {
pub fn new() -> PipelineId {
PIPELINE_NAMESPACE.with(|tls| {
let mut namespace = tls.get().expect("No namespace set for this thread!");
let new_pipeline_id = namespace.next();
let new_pipeline_id = namespace.next_pipeline_id();
tls.set(Some(namespace));
new_pipeline_id
})
}
// TODO(gw): This should be removed. It's only required because of the code
// that uses it in the devtools lib.rs file (which itself is a TODO). Once
// that is fixed, this should be removed. It also relies on the first
// call to PipelineId::new() returning (0,0), which is checked with an
// assert in handle_init_load().
pub fn fake_root_pipeline_id() -> PipelineId {
PipelineId {
namespace_id: PipelineNamespaceId(0),
index: PipelineIndex(0),
}
}
pub fn to_webrender(&self) -> webrender_traits::PipelineId {
let PipelineNamespaceId(namespace_id) = self.namespace_id;
let PipelineIndex(index) = self.index;
@ -331,6 +324,41 @@ impl fmt::Display for PipelineId {
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)]
pub struct FrameIndex(pub u32);
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)]
pub struct FrameId {
pub namespace_id: PipelineNamespaceId,
pub index: FrameIndex
}
impl FrameId {
pub fn new() -> FrameId {
PIPELINE_NAMESPACE.with(|tls| {
let mut namespace = tls.get().expect("No namespace set for this thread!");
let new_frame_id = namespace.next_frame_id();
tls.set(Some(namespace));
new_frame_id
})
}
}
impl fmt::Display for FrameId {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let PipelineNamespaceId(namespace_id) = self.namespace_id;
let FrameIndex(index) = self.index;
write!(fmt, "({},{})", namespace_id, index)
}
}
// We provide ids just for unit testing.
pub const TEST_NAMESPACE: PipelineNamespaceId = PipelineNamespaceId(1234);
pub const TEST_PIPELINE_INDEX: PipelineIndex = PipelineIndex(5678);
pub const TEST_PIPELINE_ID: PipelineId = PipelineId { namespace_id: TEST_NAMESPACE, index: TEST_PIPELINE_INDEX };
pub const TEST_FRAME_INDEX: FrameIndex = FrameIndex(8765);
pub const TEST_FRAME_ID: FrameId = FrameId { namespace_id: TEST_NAMESPACE, index: TEST_FRAME_INDEX };
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)]
pub enum FrameType {
IFrame,

View file

@ -57,7 +57,7 @@ use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
use js::jsval::JSVal;
use js::rust::Runtime;
use libc;
use msg::constellation_msg::{FrameType, PipelineId, ReferrerPolicy, WindowSizeType};
use msg::constellation_msg::{FrameId, FrameType, PipelineId, ReferrerPolicy, WindowSizeType};
use net_traits::{Metadata, NetworkError, ResourceThreads};
use net_traits::filemanager_thread::RelativePos;
use net_traits::image::base::{Image, ImageMetadata};
@ -308,7 +308,7 @@ no_jsmanaged_fields!(PropertyDeclarationBlock);
no_jsmanaged_fields!(HashSet<T>);
// These three are interdependent, if you plan to put jsmanaged data
// in one of these make sure it is propagated properly to containing structs
no_jsmanaged_fields!(FrameType, WindowSizeData, WindowSizeType, PipelineId);
no_jsmanaged_fields!(FrameId, FrameType, WindowSizeData, WindowSizeType, PipelineId);
no_jsmanaged_fields!(TimerEventId, TimerSource);
no_jsmanaged_fields!(WorkerId);
no_jsmanaged_fields!(QuirksMode);

View file

@ -38,7 +38,7 @@ use dom::window::{ReflowReason, Window};
use ipc_channel::ipc;
use js::jsapi::{JSAutoCompartment, JSContext, MutableHandleValue};
use js::jsval::{NullValue, UndefinedValue};
use msg::constellation_msg::{FrameType, LoadData, PipelineId, TraversalDirection};
use msg::constellation_msg::{FrameType, FrameId, LoadData, PipelineId, TraversalDirection};
use net_traits::response::HttpsState;
use script_layout_interface::message::ReflowQueryType;
use script_traits::{IFrameLoadInfo, MozBrowserEvent, ScriptMsg as ConstellationMsg};
@ -67,6 +67,7 @@ bitflags! {
#[dom_struct]
pub struct HTMLIFrameElement {
htmlelement: HTMLElement,
frame_id: FrameId,
pipeline_id: Cell<Option<PipelineId>>,
sandbox: MutNullableHeap<JS<DOMTokenList>>,
sandbox_allowance: Cell<Option<SandboxAllowance>>,
@ -130,6 +131,7 @@ impl HTMLIFrameElement {
let load_info = IFrameLoadInfo {
load_data: load_data,
parent_pipeline_id: global_scope.pipeline_id(),
frame_id: self.frame_id,
old_pipeline_id: old_pipeline_id,
new_pipeline_id: new_pipeline_id,
sandbox: sandboxed,
@ -181,6 +183,7 @@ impl HTMLIFrameElement {
document: &Document) -> HTMLIFrameElement {
HTMLIFrameElement {
htmlelement: HTMLElement::new_inherited(local_name, prefix, document),
frame_id: FrameId::new(),
pipeline_id: Cell::new(None),
sandbox: Default::default(),
sandbox_allowance: Cell::new(None),

View file

@ -449,6 +449,8 @@ pub struct IFrameLoadInfo {
pub load_data: Option<LoadData>,
/// Pipeline ID of the parent of this iframe
pub parent_pipeline_id: PipelineId,
/// The ID for this iframe.
pub frame_id: FrameId,
/// The old pipeline ID for this iframe, if a page was previously loaded.
pub old_pipeline_id: Option<PipelineId>,
/// The new pipeline ID that the iframe has generated.

View file

@ -19,7 +19,7 @@ use hyper::server::{Handler, Listening, Server};
use hyper::server::{Request as HyperRequest, Response as HyperResponse};
use hyper::status::StatusCode;
use hyper::uri::RequestUri;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use msg::constellation_msg::{ReferrerPolicy, TEST_PIPELINE_ID};
use net::fetch::cors_cache::CORSCache;
use net::fetch::methods::{FetchContext, fetch, fetch_with_cors_cache};
use net::http_loader::HttpState;
@ -776,8 +776,7 @@ fn test_fetch_with_devtools() {
let (mut server, url) = make_server(handler);
let origin = Origin::Origin(url.origin());
let pipeline_id = PipelineId::fake_root_pipeline_id();
let request = Request::new(url.clone(), Some(origin), false, Some(pipeline_id));
let request = Request::new(url.clone(), Some(origin), false, Some(TEST_PIPELINE_ID));
*request.referrer.borrow_mut() = Referrer::NoReferrer;
let (devtools_chan, devtools_port) = channel::<DevtoolsControlMsg>();
@ -815,7 +814,7 @@ fn test_fetch_with_devtools() {
method: Method::Get,
headers: headers,
body: None,
pipeline_id: pipeline_id,
pipeline_id: TEST_PIPELINE_ID,
startedDateTime: devhttprequest.startedDateTime,
timeStamp: devhttprequest.timeStamp,
connect_time: devhttprequest.connect_time,
@ -832,7 +831,7 @@ fn test_fetch_with_devtools() {
headers: Some(response_headers),
status: Some((200, b"OK".to_vec())),
body: None,
pipeline_id: pipeline_id,
pipeline_id: TEST_PIPELINE_ID,
};
assert_eq!(devhttprequest, httprequest);

View file

@ -18,7 +18,7 @@ use hyper::http::RawStatus;
use hyper::method::Method;
use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper::status::StatusCode;
use msg::constellation_msg::{PipelineId, ReferrerPolicy};
use msg::constellation_msg::{PipelineId, ReferrerPolicy, TEST_PIPELINE_ID};
use net::cookie::Cookie;
use net::cookie_storage::CookieStorage;
use net::hsts::HstsEntry;
@ -47,7 +47,7 @@ impl LoadOrigin for HttpTest {
None
}
fn pipeline_id(&self) -> Option<PipelineId> {
Some(PipelineId::fake_root_pipeline_id())
Some(TEST_PIPELINE_ID)
}
}
@ -472,8 +472,6 @@ fn test_request_and_response_data_with_network_messages() {
let url = Url::parse("https://mozilla.com").unwrap();
let (devtools_chan, devtools_port) = mpsc::channel::<DevtoolsControlMsg>();
// This will probably have to be changed as it uses fake_root_pipeline_id which is marked for removal.
let pipeline_id = PipelineId::fake_root_pipeline_id();
let mut load_data = LoadData::new(LoadContext::Browsing, url.clone(), &HttpTest);
let mut request_headers = Headers::new();
request_headers.set(Host { hostname: "bar.foo".to_owned(), port: None });
@ -521,7 +519,7 @@ fn test_request_and_response_data_with_network_messages() {
method: Method::Get,
headers: headers,
body: None,
pipeline_id: pipeline_id,
pipeline_id: TEST_PIPELINE_ID,
startedDateTime: devhttprequest.startedDateTime,
timeStamp: devhttprequest.timeStamp,
connect_time: devhttprequest.connect_time,
@ -538,7 +536,7 @@ fn test_request_and_response_data_with_network_messages() {
headers: Some(response_headers),
status: Some((200, b"OK".to_vec())),
body: None,
pipeline_id: pipeline_id,
pipeline_id: TEST_PIPELINE_ID,
};
assert_eq!(devhttprequest, httprequest);